On 02/03/2017 11:13 PM, Haojian Zhuang wrote:
Support Designware USB device controller on HiKey platform.
Hi,
Are there plans to support this controller as a USB host rather than just a
fastboot device?
There is a separate host mode driver for it, which they disabled on
HiKey (I think) because it broke something else, presumably fastboot.
It is the same IP as Raspberry Pi 3, and I spent some time porting
that a couple of months ago (without any result so far)
--
Ard.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Haojian Zhuang
haojian.zhuang@linaro.org
>> ---
>> .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c | 266
>> +++++++++++++++++++++
>> .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf | 46 ++++
>> 2 files changed, 312 insertions(+)
>> create mode 100644 Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
>> create mode 100644 Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
>>
>> diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
>> b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
>> new file mode 100644
>> index 0000000..60ad4d6
>> --- /dev/null
>> +++ b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
>> @@ -0,0 +1,266 @@
>> +/** @file
>> +*
>> +* Copyright (c) 2015-2017, Linaro. 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 <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/IoLib.h>
>> +#include <Library/TimerLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/UefiRuntimeServicesTableLib.h>
>> +
>> +#include <Protocol/EmbeddedGpio.h>
>> +#include <Protocol/DwUsb.h>
>> +
>> +#include <Hi6220.h>
>> +
>> +
>> +#define USB_SEL_GPIO0_3 3 // GPIO 0_3
>> +#define USB_5V_HUB_EN 7 // GPIO 0_7
>> +#define USB_ID_DET_GPIO2_5 21 // GPIO 2_5
>> +#define USB_VBUS_DET_GPIO2_6 22 // GPIO 2_6
>> +
>> +// Jumper on pin5-6 of J15 determines whether boot to fastboot
>> +#define DETECT_J15_FASTBOOT 24 // GPIO 3_0
>> +
>> +STATIC EMBEDDED_GPIO *mGpio;
>> +
>> +STATIC
>> +VOID
>> +HiKeyDetectUsbModeInit (
>> + IN VOID
>> + )
>> +{
>> + EFI_STATUS Status;
>> +
>> + /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */
>> + MmioWrite32 (0xf8001864, 1);
>> + MmioWrite32 (0xf8001868, 1);
>> +
>> + Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID
>> **)&mGpio);
>> + ASSERT_EFI_ERROR (Status);
>> + Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0);
>> + ASSERT_EFI_ERROR (Status);
>> + Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0);
>> + ASSERT_EFI_ERROR (Status);
>> + MicroSecondDelay (1000);
>> +
>> + Status = mGpio->Set (mGpio, USB_ID_DET_GPIO2_5, GPIO_MODE_INPUT);
>> + ASSERT_EFI_ERROR (Status);
>> + Status = mGpio->Set (mGpio, USB_VBUS_DET_GPIO2_6, GPIO_MODE_INPUT);
>> + ASSERT_EFI_ERROR (Status);
>> +}
>> +
>> +UINTN
>> +HiKeyGetUsbMode (
>> + IN VOID
>> + )
>> +{
>> +#if 0
>> + EFI_STATUS Status;
>> + UINTN GpioId, GpioVbus;
>> + UINTN Value;
>> +
>> + Status = mGpio->Get (mGpio, USB_ID_DET_GPIO2_5, &Value);
>> + ASSERT_EFI_ERROR (Status);
>> + GpioId = Value;
>> + Status = mGpio->Get (mGpio, USB_VBUS_DET_GPIO2_6, &Value);
>> + ASSERT_EFI_ERROR (Status);
>> + GpioVbus = Value;
>> +
>> +DEBUG ((DEBUG_ERROR, "#%a, %d, GpioId:%d, GpioVbus:%d\n", __func__,
>> __LINE__, GpioId, GpioVbus));
>> + if ((GpioId == 1) && (GpioVbus == 0)) {
>> + return USB_DEVICE_MODE;
>> + } else if ((GpioId == 0) && (GpioVbus == 1)) {
>> + return USB_CABLE_NOT_ATTACHED;
>> + }
>> + return USB_HOST_MODE;
>> +#else
>> + return USB_DEVICE_MODE;
>> +#endif
>> +}
>> +
>> +EFI_STATUS
>> +HiKeyUsbPhyInit (
>> + IN UINT8 Mode
>> + )
>> +{
>> + UINTN Value;
>> + UINT32 Data;
>> +
>> + HiKeyDetectUsbModeInit ();
>> +
>> + //setup clock
>> + MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN0, BIT4);
>> + do {
>> + Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CLKSTAT0);
>> + } while ((Value & BIT4) == 0);
>> +
>> + //setup phy
>> + Data = RST0_USBOTG_BUS | RST0_POR_PICOPHY |
>> + RST0_USBOTG | RST0_USBOTG_32K;
>> + MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, Data);
>> + do {
>> + Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT0);
>> + Value &= Data;
>> + } while (Value);
>> +
>> + Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4);
>> + Value &= ~(CTRL4_PICO_SIDDQ | CTRL4_FPGA_EXT_PHY_SEL |
>> + CTRL4_OTG_PHY_SEL);
>> + Value |= CTRL4_PICO_VBUSVLDEXT | CTRL4_PICO_VBUSVLDEXTSEL;
>> + MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4, Value);
>> + MicroSecondDelay (1000);
>> +
>> + //If Mode = 1, USB in Device Mode
>> + //If Mode = 0, USB in Host Mode
>> + if (Mode == USB_DEVICE_MODE) {
>> + if (HiKeyGetUsbMode () == USB_DEVICE_MODE) {
>> + DEBUG ((DEBUG_ERROR, "usb work as device mode.\n"));
>> + } else {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
>> + Value &= ~CTRL5_PICOPHY_BC_MODE;
>> + MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value);
>> + MicroSecondDelay (20000);
>> + } else {
>> + if (HiKeyGetUsbMode () == USB_HOST_MODE) {
>> + DEBUG ((DEBUG_ERROR, "usb work as host mode.\n"));
>> + } else {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + /*CTRL5*/
>> + Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
>> + Data &= ~CTRL5_PICOPHY_BC_MODE;
>> + Data |= CTRL5_USBOTG_RES_SEL | CTRL5_PICOPHY_ACAENB |
>> + CTRL5_PICOPHY_VDATDETENB | CTRL5_PICOPHY_DCDENB;
>> + MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Data);
>> + MicroSecondDelay (20000);
>> + MmioWrite32 (PERI_CTRL_BASE + 0x018, 0x70533483); //EYE_PATTERN
>> +
>> + MicroSecondDelay (5000);
>> + }
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetLang (
>> + OUT CHAR16 *Lang,
>> + OUT UINT8 *Length
>> + )
>> +{
>> + if ((Lang == NULL) || (Length == NULL)) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> + Lang[0] = 0x409;
>> + *Length = sizeof (CHAR16);
>> + return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetManuFacturer (
>> + OUT CHAR16 *ManuFacturer,
>> + OUT UINT8 *Length
>> + )
>> +{
>> + UINTN VariableSize;
>> + CHAR16 DataUnicode[MANU_FACTURER_STRING_LENGTH];
>> +
>> + if ((ManuFacturer == NULL) || (Length == NULL)) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> + VariableSize = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
>> + ZeroMem (DataUnicode, MANU_FACTURER_STRING_LENGTH * sizeof(CHAR16));
>> + StrCpy (DataUnicode, L"96Boards");
>> + CopyMem (ManuFacturer, DataUnicode, VariableSize);
>> + *Length = VariableSize;
>> + return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetProduct (
>> + OUT CHAR16 *Product,
>> + OUT UINT8 *Length
>> + )
>> +{
>> + UINTN VariableSize;
>> + CHAR16 DataUnicode[PRODUCT_STRING_LENGTH];
>> +
>> + if ((Product == NULL) || (Length == NULL)) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> + VariableSize = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
>> + ZeroMem (DataUnicode, PRODUCT_STRING_LENGTH * sizeof(CHAR16));
>> + StrCpy (DataUnicode, L"HiKey");
>> + CopyMem (Product, DataUnicode, VariableSize);
>> + *Length = VariableSize;
>> + return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetSerialNo (
>> + OUT CHAR16 *SerialNo,
>> + OUT UINT8 *Length
>> + )
>> +{
>> + UINTN VariableSize;
>> + CHAR16 DataUnicode[SERIAL_STRING_LENGTH];
>> +
>> + if ((SerialNo == NULL) || (Length == NULL)) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> + VariableSize = SERIAL_STRING_LENGTH * sizeof (CHAR16);
>> + ZeroMem (DataUnicode, SERIAL_STRING_LENGTH * sizeof(CHAR16));
>> + StrCpy (DataUnicode, L"0123456789abcdef");
>> + CopyMem (SerialNo, DataUnicode, VariableSize);
>> + *Length = VariableSize;
>> + return EFI_SUCCESS;
>> +}
>> +
>> +DW_USB_PROTOCOL mDwUsbDevice = {
>> + HiKeyUsbGetLang,
>> + HiKeyUsbGetManuFacturer,
>> + HiKeyUsbGetProduct,
>> + HiKeyUsbGetSerialNo,
>> + HiKeyUsbPhyInit
>> +};
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbEntryPoint (
>> + IN EFI_HANDLE ImageHandle,
>> + IN EFI_SYSTEM_TABLE *SystemTable
>> + )
>> +{
>> + EFI_STATUS Status;
>> +
>> + Status = gBS->InstallProtocolInterface (
>> + &ImageHandle,
>> + &gDwUsbProtocolGuid,
>> + EFI_NATIVE_INTERFACE,
>> + &mDwUsbDevice
>> + );
>> + if (EFI_ERROR (Status)) {
>> + return Status;
>> + }
>> + return Status;
>> +}
>> diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
>> b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
>> new file mode 100644
>> index 0000000..75ff599
>> --- /dev/null
>> +++ b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
>> @@ -0,0 +1,46 @@
>> +#/** @file
>> +#
>> +# Copyright (c) 2015-2017, Linaro. 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.
>> +#
>> +#
>> +#**/
>> +
>> +[Defines]
>> + INF_VERSION = 0x00010019
>> + BASE_NAME = HiKeyUsbDxe
>> + FILE_GUID = c5c7089e-9b00-448c-8b23-a552688e2833
>> + MODULE_TYPE = UEFI_DRIVER
>> + VERSION_STRING = 1.0
>> + ENTRY_POINT = HiKeyUsbEntryPoint
>> +
>> +[Sources.common]
>> + HiKeyUsbDxe.c
>> +
>> +[LibraryClasses]
>> + DebugLib
>> + IoLib
>> + TimerLib
>> + UefiBootServicesTableLib
>> + UefiDriverEntryPoint
>> +
>> +[Protocols]
>> + gDwUsbProtocolGuid
>> + gEfiDriverBindingProtocolGuid
>> + gEmbeddedGpioProtocolGuid
>> +
>> +[Packages]
>> + MdePkg/MdePkg.dec
>> + MdeModulePkg/MdeModulePkg.dec
>> + EmbeddedPkg/EmbeddedPkg.dec
>> + OpenPlatformPkg/Drivers/Usb/DwUsbDxe/DwUsbDxe.dec
>> + OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dec
>> +
>> +[Depex]
>> + BEFORE gDwUsbDeviceGuid
>>
>