[Linaro-uefi,v3,4/5] Platforms/Hisilicon/HiKey: support designware USB controller

Message ID 1486998621-30420-5-git-send-email-haojian.zhuang@linaro.org
State Superseded
Headers show
Series
  • add drivers for Android Fastboot App on HiKey
Related show

Commit Message

Haojian Zhuang Feb. 13, 2017, 3:10 p.m.
Support Designware USB device controller on HiKey platform.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c      | 271 +++++++++++++++++++++
 .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf    |  46 ++++
 2 files changed, 317 insertions(+)
 create mode 100644 Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
 create mode 100644 Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf

Comments

Leif Lindholm Feb. 13, 2017, 4:40 p.m. | #1
On Mon, Feb 13, 2017 at 11:10:20PM +0800, Haojian Zhuang wrote:
> Support Designware USB device controller on HiKey platform.
> 
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
> ---
>  .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c      | 271 +++++++++++++++++++++
>  .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf    |  46 ++++
>  2 files changed, 317 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..b121d0b
> --- /dev/null
> +++ b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
> @@ -0,0 +1,271 @@
> +/** @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
> +
> +#define IOCG_GPIO0_BASE          0xF8001800
> +#define IOCG_GPIO0_3_OFFSET      0x1C
> +#define IOCG_GPIO0_7_OFFSET      0x2C
> +#define IOCG_GPIO2_5_OFFSET      0x64
> +#define IOCG_GPIO2_6_OFFSET      0x68
> +
> +#define IOCG_PULLUP              1
> +#define IOCG_PULLDOWN            2
> +
> +#define USB_EYE_PATTERN          0x70533483
> +
> +#define LANG_EN                  0x409
> +
> +STATIC EMBEDDED_GPIO *mGpio;
> +
> +STATIC
> +EFI_STATUS
> +HiKeyDetectUsbModeInit (
> +  IN VOID
> +  )
> +{
> +  EFI_STATUS     Status;
> +
> +  /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */
> +  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_5_OFFSET, IOCG_PULLUP);
> +  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_6_OFFSET, IOCG_PULLUP);
> +
> +  Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&mGpio);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "Can't locate gEmbeddedGpioProtocolGuid\n"));
> +    return Status;
> +  }
> +  ASSERT_EFI_ERROR (Status);

So, I realise my discussion with Ard may have been difficult to keep
track of. 

Ard pointed out that your previous version (only ASSERT, no return) is
completely valid if this module has an explicit depex on
gEmbeddedGpioProtocolGuid. We agreed that in this case it would make
sense to also add a comment ponting this fact out.
However, this module does not have such an explicit depex.

But both the error return and the ASSERT_EFI_ERROR make no sense.

So, please, either add the depex to the .inf file (and a comment
explaining that the depex guarantees the protocol will be available)
or delete the ASSERT_EFI_ERROR line.

> +  /* power on USB HUB */
> +  Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0);
> +  ASSERT_EFI_ERROR (Status);
> +  /* start to detect USB device or host */
> +  Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  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);
> +  return EFI_SUCCESS;
> +}
> +
> +UINTN
> +HiKeyGetUsbMode (
> +  IN VOID
> +  )
> +{
> +  EFI_STATUS     Status;
> +  UINTN          GpioId, GpioVbus;
> +  UINTN          Value;

I don't think this "Value" variable adds anything useful, can you send
off pointers directly to GpioId/GpioVbus instead?

> +
> +  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;
> +
> +  if ((GpioId == 1) && (GpioVbus == 0)) {
> +    return USB_DEVICE_MODE;
> +  } else if ((GpioId == 0) && (GpioVbus == 1)) {
> +    return USB_CABLE_NOT_ATTACHED;
> +  }
> +  return USB_HOST_MODE;
> +}
> +
> +EFI_STATUS
> +HiKeyUsbPhyInit (
> +  IN UINT8        Mode
> +  )
> +{
> +  UINTN          Value;
> +  UINT32         Data;
> +  EFI_STATUS     Status;
> +
> +  Status = HiKeyDetectUsbModeInit ();
> +  if (EFI_ERROR (Status)) {
> +    return Status;
> +  }
> +
> +  //setup clock
> +  MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN0, BIT4);

Comment from previous revision not addressed:
---
What does BIT4 mean in this context?
Can a #define with a more descriptive name be created?
---

> +  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);
> +

OK, I'll try to clarify my feedback from last time:

First of all

     if (HiKeyGetUsbMode () != Mode) {
       return EFI_INVALID_PARAMETER;
     }

should happen before everything below.

> +  //If Mode = 1, USB in Device Mode
> +  //If Mode = 0, USB in Host Mode
> +  if (Mode == USB_DEVICE_MODE) {
> +    if (HiKeyGetUsbMode () != USB_DEVICE_MODE) {
> +      return EFI_INVALID_PARAMETER;
> +    }

And then the above test can be deleted.

> +    DEBUG ((DEBUG_INFO, "usb work as device mode.\n"));
> +
> +    Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
> +    Value &= ~CTRL5_PICOPHY_BC_MODE;
> +    MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value);
> +    /* wait for stable */

Why 20ms?

> +    MicroSecondDelay (20000);
> +  } else {
> +    if (HiKeyGetUsbMode () != USB_HOST_MODE) {
> +      return EFI_INVALID_PARAMETER;
> +    }

And delete the above test.

> +    DEBUG ((DEBUG_INFO, "usb work as host mode.\n"));
> +
> +    /*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);
> +    /* wait for stable */
> +    MicroSecondDelay (20000);

Why 20ms?

> +    MmioWrite32 (PERI_CTRL_BASE + 0x018, USB_EYE_PATTERN);

A #define for that 0x018 as well please.
(And yes, with the USB_EYE_PATTERN #define, the comment is no longer
needed.)

> +    /* wait for eye pattern effective */
> +    MicroSecondDelay (5000);

Why 5ms?

> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +HiKeyUsbGetLang (
> +  OUT CHAR16            *Lang,
> +  OUT UINT8             *Length
> +  )
> +{
> +  if ((Lang == NULL) || (Length == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  Lang[0] = LANG_EN;

That reminds me I should upstream a header file to edk2 for these
codes. Doesn't matter for this patch though, so this is fine.

> +  *Length = sizeof (CHAR16);
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +HiKeyUsbGetManuFacturer (

Ass commented on previous revision, please change all occurences of
"ManuFacturer" to
"Manufacturer"

> +  OUT CHAR16            *ManuFacturer,
> +  OUT UINT8             *Length
> +  )
> +{
> +  CHAR16                 DataUnicode[] = L"96Boards";
> +
> +  if ((ManuFacturer == NULL) || (Length == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  StrCpy (ManuFacturer, DataUnicode);
> +  /* include '\0' for string */
> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);

This is still not correct - now there is _no_ sanity checking of
string length.

> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +HiKeyUsbGetProduct (
> +  OUT CHAR16            *Product,
> +  OUT UINT8             *Length
> +  )
> +{
> +  CHAR16                 DataUnicode[] = L"HiKey";
> +
> +  if ((Product == NULL) || (Length == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  StrCpy (Product, DataUnicode);
> +  /* include '\0' for string */
> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +HiKeyUsbGetSerialNo (
> +  OUT CHAR16            *SerialNo,
> +  OUT UINT8             *Length
> +  )
> +{
> +  CHAR16                 DataUnicode[] = L"0123456789abcdef";
> +
> +  if ((SerialNo == NULL) || (Length == NULL)) {
> +    return EFI_INVALID_PARAMETER;
> +  }
> +  StrCpy (SerialNo, DataUnicode);
> +  /* include '\0' for string */
> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
> +  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
> +                  );
> +  return Status;
> +}
> diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
> new file mode 100644
> index 0000000..57d639a
> --- /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]
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  OpenPlatformPkg/Drivers/Usb/DwUsbDxe/DwUsbDxe.dec
> +  OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dec
> +
> +[Depex]
> +  TRUE
> -- 
> 2.7.4
>
Haojian Zhuang Feb. 14, 2017, 3:39 p.m. | #2
On 14 February 2017 at 00:40, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Mon, Feb 13, 2017 at 11:10:20PM +0800, Haojian Zhuang wrote:
>> Support Designware USB device controller on HiKey platform.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
>> ---
>>  .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c      | 271 +++++++++++++++++++++
>>  .../Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf    |  46 ++++
>>  2 files changed, 317 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..b121d0b
>> --- /dev/null
>> +++ b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
>> @@ -0,0 +1,271 @@
>> +/** @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
>> +
>> +#define IOCG_GPIO0_BASE          0xF8001800
>> +#define IOCG_GPIO0_3_OFFSET      0x1C
>> +#define IOCG_GPIO0_7_OFFSET      0x2C
>> +#define IOCG_GPIO2_5_OFFSET      0x64
>> +#define IOCG_GPIO2_6_OFFSET      0x68
>> +
>> +#define IOCG_PULLUP              1
>> +#define IOCG_PULLDOWN            2
>> +
>> +#define USB_EYE_PATTERN          0x70533483
>> +
>> +#define LANG_EN                  0x409
>> +
>> +STATIC EMBEDDED_GPIO *mGpio;
>> +
>> +STATIC
>> +EFI_STATUS
>> +HiKeyDetectUsbModeInit (
>> +  IN VOID
>> +  )
>> +{
>> +  EFI_STATUS     Status;
>> +
>> +  /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */
>> +  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_5_OFFSET, IOCG_PULLUP);
>> +  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_6_OFFSET, IOCG_PULLUP);
>> +
>> +  Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&mGpio);
>> +  if (EFI_ERROR (Status)) {
>> +    DEBUG ((DEBUG_ERROR, "Can't locate gEmbeddedGpioProtocolGuid\n"));
>> +    return Status;
>> +  }
>> +  ASSERT_EFI_ERROR (Status);
>
> So, I realise my discussion with Ard may have been difficult to keep
> track of.
>
> Ard pointed out that your previous version (only ASSERT, no return) is
> completely valid if this module has an explicit depex on
> gEmbeddedGpioProtocolGuid. We agreed that in this case it would make
> sense to also add a comment ponting this fact out.
> However, this module does not have such an explicit depex.
>
> But both the error return and the ASSERT_EFI_ERROR make no sense.
>
> So, please, either add the depex to the .inf file (and a comment
> explaining that the depex guarantees the protocol will be available)
> or delete the ASSERT_EFI_ERROR line.
>
>> +  /* power on USB HUB */
>> +  Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0);
>> +  ASSERT_EFI_ERROR (Status);
>> +  /* start to detect USB device or host */
>> +  Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0);
>> +  ASSERT_EFI_ERROR (Status);
>> +
>> +  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);
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +UINTN
>> +HiKeyGetUsbMode (
>> +  IN VOID
>> +  )
>> +{
>> +  EFI_STATUS     Status;
>> +  UINTN          GpioId, GpioVbus;
>> +  UINTN          Value;
>
> I don't think this "Value" variable adds anything useful, can you send
> off pointers directly to GpioId/GpioVbus instead?
>
>> +
>> +  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;
>> +
>> +  if ((GpioId == 1) && (GpioVbus == 0)) {
>> +    return USB_DEVICE_MODE;
>> +  } else if ((GpioId == 0) && (GpioVbus == 1)) {
>> +    return USB_CABLE_NOT_ATTACHED;
>> +  }
>> +  return USB_HOST_MODE;
>> +}
>> +
>> +EFI_STATUS
>> +HiKeyUsbPhyInit (
>> +  IN UINT8        Mode
>> +  )
>> +{
>> +  UINTN          Value;
>> +  UINT32         Data;
>> +  EFI_STATUS     Status;
>> +
>> +  Status = HiKeyDetectUsbModeInit ();
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  //setup clock
>> +  MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN0, BIT4);
>
> Comment from previous revision not addressed:
> ---
> What does BIT4 mean in this context?
> Can a #define with a more descriptive name be created?
> ---
>
>> +  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);
>> +
>
> OK, I'll try to clarify my feedback from last time:
>
> First of all
>
>      if (HiKeyGetUsbMode () != Mode) {
>        return EFI_INVALID_PARAMETER;
>      }
>
> should happen before everything below.
>
>> +  //If Mode = 1, USB in Device Mode
>> +  //If Mode = 0, USB in Host Mode
>> +  if (Mode == USB_DEVICE_MODE) {
>> +    if (HiKeyGetUsbMode () != USB_DEVICE_MODE) {
>> +      return EFI_INVALID_PARAMETER;
>> +    }
>
> And then the above test can be deleted.
>
>> +    DEBUG ((DEBUG_INFO, "usb work as device mode.\n"));
>> +
>> +    Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
>> +    Value &= ~CTRL5_PICOPHY_BC_MODE;
>> +    MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value);
>> +    /* wait for stable */
>
> Why 20ms?
>
>> +    MicroSecondDelay (20000);
>> +  } else {
>> +    if (HiKeyGetUsbMode () != USB_HOST_MODE) {
>> +      return EFI_INVALID_PARAMETER;
>> +    }
>
> And delete the above test.
>
>> +    DEBUG ((DEBUG_INFO, "usb work as host mode.\n"));
>> +
>> +    /*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);
>> +    /* wait for stable */
>> +    MicroSecondDelay (20000);
>
> Why 20ms?
>
>> +    MmioWrite32 (PERI_CTRL_BASE + 0x018, USB_EYE_PATTERN);
>
> A #define for that 0x018 as well please.
> (And yes, with the USB_EYE_PATTERN #define, the comment is no longer
> needed.)
>
>> +    /* wait for eye pattern effective */
>> +    MicroSecondDelay (5000);
>
> Why 5ms?

I don't know in details. All these delays are necessary, and they could
not be replaced by memory barrier. All of these are porting from vendor's
driver.

>
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetLang (
>> +  OUT CHAR16            *Lang,
>> +  OUT UINT8             *Length
>> +  )
>> +{
>> +  if ((Lang == NULL) || (Length == NULL)) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  Lang[0] = LANG_EN;
>
> That reminds me I should upstream a header file to edk2 for these
> codes. Doesn't matter for this patch though, so this is fine.
>
>> +  *Length = sizeof (CHAR16);
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetManuFacturer (
>
> Ass commented on previous revision, please change all occurences of
> "ManuFacturer" to
> "Manufacturer"
>
>> +  OUT CHAR16            *ManuFacturer,
>> +  OUT UINT8             *Length
>> +  )
>> +{
>> +  CHAR16                 DataUnicode[] = L"96Boards";
>> +
>> +  if ((ManuFacturer == NULL) || (Length == NULL)) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  StrCpy (ManuFacturer, DataUnicode);
>> +  /* include '\0' for string */
>> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
>
> This is still not correct - now there is _no_ sanity checking of
> string length.

I need the terminated '\0' character. Since it'll be sent by USB driver.
Without this, the last character will dispear.

>
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetProduct (
>> +  OUT CHAR16            *Product,
>> +  OUT UINT8             *Length
>> +  )
>> +{
>> +  CHAR16                 DataUnicode[] = L"HiKey";
>> +
>> +  if ((Product == NULL) || (Length == NULL)) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  StrCpy (Product, DataUnicode);
>> +  /* include '\0' for string */
>> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +HiKeyUsbGetSerialNo (
>> +  OUT CHAR16            *SerialNo,
>> +  OUT UINT8             *Length
>> +  )
>> +{
>> +  CHAR16                 DataUnicode[] = L"0123456789abcdef";
>> +
>> +  if ((SerialNo == NULL) || (Length == NULL)) {
>> +    return EFI_INVALID_PARAMETER;
>> +  }
>> +  StrCpy (SerialNo, DataUnicode);
>> +  /* include '\0' for string */
>> +  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
>> +  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
>> +                  );
>> +  return Status;
>> +}
>> diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
>> new file mode 100644
>> index 0000000..57d639a
>> --- /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]
>> +  EmbeddedPkg/EmbeddedPkg.dec
>> +  MdeModulePkg/MdeModulePkg.dec
>> +  MdePkg/MdePkg.dec
>> +  OpenPlatformPkg/Drivers/Usb/DwUsbDxe/DwUsbDxe.dec
>> +  OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dec
>> +
>> +[Depex]
>> +  TRUE
>> --
>> 2.7.4
>>

Patch

diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
new file mode 100644
index 0000000..b121d0b
--- /dev/null
+++ b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
@@ -0,0 +1,271 @@ 
+/** @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
+
+#define IOCG_GPIO0_BASE          0xF8001800
+#define IOCG_GPIO0_3_OFFSET      0x1C
+#define IOCG_GPIO0_7_OFFSET      0x2C
+#define IOCG_GPIO2_5_OFFSET      0x64
+#define IOCG_GPIO2_6_OFFSET      0x68
+
+#define IOCG_PULLUP              1
+#define IOCG_PULLDOWN            2
+
+#define USB_EYE_PATTERN          0x70533483
+
+#define LANG_EN                  0x409
+
+STATIC EMBEDDED_GPIO *mGpio;
+
+STATIC
+EFI_STATUS
+HiKeyDetectUsbModeInit (
+  IN VOID
+  )
+{
+  EFI_STATUS     Status;
+
+  /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */
+  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_5_OFFSET, IOCG_PULLUP);
+  MmioWrite32 (IOCG_GPIO0_BASE + IOCG_GPIO2_6_OFFSET, IOCG_PULLUP);
+
+  Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&mGpio);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Can't locate gEmbeddedGpioProtocolGuid\n"));
+    return Status;
+  }
+  ASSERT_EFI_ERROR (Status);
+  /* power on USB HUB */
+  Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0);
+  ASSERT_EFI_ERROR (Status);
+  /* start to detect USB device or host */
+  Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0);
+  ASSERT_EFI_ERROR (Status);
+
+  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);
+  return EFI_SUCCESS;
+}
+
+UINTN
+HiKeyGetUsbMode (
+  IN VOID
+  )
+{
+  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;
+
+  if ((GpioId == 1) && (GpioVbus == 0)) {
+    return USB_DEVICE_MODE;
+  } else if ((GpioId == 0) && (GpioVbus == 1)) {
+    return USB_CABLE_NOT_ATTACHED;
+  }
+  return USB_HOST_MODE;
+}
+
+EFI_STATUS
+HiKeyUsbPhyInit (
+  IN UINT8        Mode
+  )
+{
+  UINTN          Value;
+  UINT32         Data;
+  EFI_STATUS     Status;
+
+  Status = HiKeyDetectUsbModeInit ();
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  //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);
+
+  //If Mode = 1, USB in Device Mode
+  //If Mode = 0, USB in Host Mode
+  if (Mode == USB_DEVICE_MODE) {
+    if (HiKeyGetUsbMode () != USB_DEVICE_MODE) {
+      return EFI_INVALID_PARAMETER;
+    }
+    DEBUG ((DEBUG_INFO, "usb work as device mode.\n"));
+
+    Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
+    Value &= ~CTRL5_PICOPHY_BC_MODE;
+    MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value);
+    /* wait for stable */
+    MicroSecondDelay (20000);
+  } else {
+    if (HiKeyGetUsbMode () != USB_HOST_MODE) {
+      return EFI_INVALID_PARAMETER;
+    }
+    DEBUG ((DEBUG_INFO, "usb work as host mode.\n"));
+
+    /*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);
+    /* wait for stable */
+    MicroSecondDelay (20000);
+    MmioWrite32 (PERI_CTRL_BASE + 0x018, USB_EYE_PATTERN);
+    /* wait for eye pattern effective */
+    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] = LANG_EN;
+  *Length = sizeof (CHAR16);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKeyUsbGetManuFacturer (
+  OUT CHAR16            *ManuFacturer,
+  OUT UINT8             *Length
+  )
+{
+  CHAR16                 DataUnicode[] = L"96Boards";
+
+  if ((ManuFacturer == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  StrCpy (ManuFacturer, DataUnicode);
+  /* include '\0' for string */
+  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKeyUsbGetProduct (
+  OUT CHAR16            *Product,
+  OUT UINT8             *Length
+  )
+{
+  CHAR16                 DataUnicode[] = L"HiKey";
+
+  if ((Product == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  StrCpy (Product, DataUnicode);
+  /* include '\0' for string */
+  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+HiKeyUsbGetSerialNo (
+  OUT CHAR16            *SerialNo,
+  OUT UINT8             *Length
+  )
+{
+  CHAR16                 DataUnicode[] = L"0123456789abcdef";
+
+  if ((SerialNo == NULL) || (Length == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+  StrCpy (SerialNo, DataUnicode);
+  /* include '\0' for string */
+  *Length = (StrLen (DataUnicode) + 1) * sizeof (CHAR16);
+  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
+                  );
+  return Status;
+}
diff --git a/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf b/Platforms/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
new file mode 100644
index 0000000..57d639a
--- /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]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  OpenPlatformPkg/Drivers/Usb/DwUsbDxe/DwUsbDxe.dec
+  OpenPlatformPkg/Platforms/Hisilicon/HiKey/HiKey.dec
+
+[Depex]
+  TRUE