public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk-platforms v1 0/4] enable usb driver on HiKey
@ 2018-08-21 11:35 Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 1/4] Platform/HiKey: add more register definitions Haojian Zhuang
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Haojian Zhuang @ 2018-08-21 11:35 UTC (permalink / raw)
  To: edk2-devel

Changelog:
v1:
  * Enable USB driver on HiKey platform.

Haojian Zhuang (4):
  Platform/HiKey: add more register definitions
  Platform/HiKey: add usb platform driver
  Platform/HiKey: add fastboot platform driver
  Platform/HiKey: enable usb driver

 Platform/Hisilicon/HiKey/HiKey.dec                             |   2 +
 Platform/Hisilicon/HiKey/HiKey.dsc                             |  13 +
 Platform/Hisilicon/HiKey/HiKey.fdf                             |   3 +
 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf |  61 ++
 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf           |  46 ++
 Silicon/Hisilicon/Hi6220/Include/Hi6220.h                      |  53 ++
 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c   | 630 ++++++++++++++++++++
 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c             | 280 +++++++++
 8 files changed, 1088 insertions(+)
 create mode 100644 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
 create mode 100644 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
 create mode 100644 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c
 create mode 100644 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
-- 
2.7.4



^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH edk-platforms v1 1/4] Platform/HiKey: add more register definitions
  2018-08-21 11:35 [PATCH edk-platforms v1 0/4] enable usb driver on HiKey Haojian Zhuang
@ 2018-08-21 11:35 ` Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 2/4] Platform/HiKey: add usb platform driver Haojian Zhuang
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Haojian Zhuang @ 2018-08-21 11:35 UTC (permalink / raw)
  To: edk2-devel

These register definitions are used in USB device driver.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Silicon/Hisilicon/Hi6220/Include/Hi6220.h | 53 ++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/Silicon/Hisilicon/Hi6220/Include/Hi6220.h b/Silicon/Hisilicon/Hi6220/Include/Hi6220.h
index 9b2508955772..ff0ba691bb61 100644
--- a/Silicon/Hisilicon/Hi6220/Include/Hi6220.h
+++ b/Silicon/Hisilicon/Hi6220/Include/Hi6220.h
@@ -29,6 +29,23 @@
 #define IOCG_BASE                               0xF7010800
 #define IOCG_084_REG                            (IOCG_BASE + 0x150)
 
+#define GPIO4_CTRL_BASE                         0xF7020000
+#define GPIO5_CTRL_BASE                         0xF7021000
+#define GPIO6_CTRL_BASE                         0xF7022000
+#define GPIO7_CTRL_BASE                         0xF7023000
+#define GPIO8_CTRL_BASE                         0xF7024000
+#define GPIO9_CTRL_BASE                         0xF7025000
+#define GPIO10_CTRL_BASE                        0xF7026000
+#define GPIO11_CTRL_BASE                        0xF7027000
+#define GPIO12_CTRL_BASE                        0xF7028000
+#define GPIO13_CTRL_BASE                        0xF7029000
+#define GPIO14_CTRL_BASE                        0xF702A000
+#define GPIO15_CTRL_BASE                        0xF702B000
+#define GPIO16_CTRL_BASE                        0xF702C000
+#define GPIO17_CTRL_BASE                        0xF702D000
+#define GPIO18_CTRL_BASE                        0xF702E000
+#define GPIO19_CTRL_BASE                        0xF702F000
+
 #define PERI_CTRL_BASE                          0xF7030000
 #define SC_PERIPH_CTRL4                         0x00C
 #define CTRL4_FPGA_EXT_PHY_SEL                  BIT3
@@ -51,18 +68,47 @@
 
 #define SC_PERIPH_CTRL8                         0x018
 #define SC_PERIPH_CLKEN0                        0x200
+
+#define PERIPH_CLKEN0_USBOTG                    BIT4
+
 #define SC_PERIPH_CLKDIS0                       0x204
 #define SC_PERIPH_CLKSTAT0                      0x208
 
+#define SC_PERIPH_CLKEN3                        0x230
 #define SC_PERIPH_RSTEN0                        0x300
 #define SC_PERIPH_RSTDIS0                       0x304
 #define SC_PERIPH_RSTSTAT0                      0x308
+#define SC_PERIPH_RSTEN3                        0x330
+#define SC_PERIPH_RSTDIS3                       0x334
+#define SC_PERIPH_RSTSTAT3                      0x338
 
 #define RST0_USBOTG_BUS                         BIT4
 #define RST0_POR_PICOPHY                        BIT5
 #define RST0_USBOTG                             BIT6
 #define RST0_USBOTG_32K                         BIT7
 
+/* SC_PERIPH_RSTEN0/RSTDIS0/RSTSTAT0 */
+#define PERIPH_RST0_MMC2                        (1 << 2)
+
+/* SC_PERIPH_RSTEN3/RSTDIS3/RSTSTAT3 */
+#define PERIPH_RST3_CSSYS                       (1 << 0)
+#define PERIPH_RST3_I2C0                        (1 << 1)
+#define PERIPH_RST3_I2C1                        (1 << 2)
+#define PERIPH_RST3_I2C2                        (1 << 3)
+#define PERIPH_RST3_I2C3                        (1 << 4)
+#define PERIPH_RST3_UART1                       (1 << 5)
+#define PERIPH_RST3_UART2                       (1 << 6)
+#define PERIPH_RST3_UART3                       (1 << 7)
+#define PERIPH_RST3_UART4                       (1 << 8)
+#define PERIPH_RST3_SSP                         (1 << 9)
+#define PERIPH_RST3_PWM                         (1 << 10)
+#define PERIPH_RST3_BLPWM                       (1 << 11)
+#define PERIPH_RST3_TSENSOR                     (1 << 12)
+#define PERIPH_RST3_DAPB                        (1 << 18)
+#define PERIPH_RST3_HKADC                       (1 << 19)
+#define PERIPH_RST3_CODEC_SSI                   (1 << 20)
+#define PERIPH_RST3_PMUSSI1                     (1 << 22)
+
 #define EYE_PATTERN_PARA                        0x7053348c
 
 #define MDDRC_AXI_BASE                          0xF7120000
@@ -80,4 +126,11 @@
 
 #define PMUSSI_BASE                             0xF8000000
 
+#define PMUSSI_REG(x)                           (PMUSSI_BASE + ((x) << 2))
+
+#define GPIO0_CTRL_BASE                         0xF8011000
+#define GPIO1_CTRL_BASE                         0xF8012000
+#define GPIO2_CTRL_BASE                         0xF8013000
+#define GPIO3_CTRL_BASE                         0xF8014000
+
 #endif /* __HI6220_H__ */
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH edk-platforms v1 2/4] Platform/HiKey: add usb platform driver
  2018-08-21 11:35 [PATCH edk-platforms v1 0/4] enable usb driver on HiKey Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 1/4] Platform/HiKey: add more register definitions Haojian Zhuang
@ 2018-08-21 11:35 ` Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 3/4] Platform/HiKey: add fastboot " Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 4/4] Platform/HiKey: enable usb driver Haojian Zhuang
  3 siblings, 0 replies; 5+ messages in thread
From: Haojian Zhuang @ 2018-08-21 11:35 UTC (permalink / raw)
  To: edk2-devel

Implement DwUsb protocol in the usb platform driver on HiKey
platform.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf |  46 ++++
 Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c   | 280 ++++++++++++++++++++
 2 files changed, 326 insertions(+)

diff --git a/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf b/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
new file mode 100644
index 000000000000..bcba3f758c1a
--- /dev/null
+++ b/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#  Copyright (c) 2018, 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/Drivers/DwUsbDxe/DwUsbDxe.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  MdePkg/MdePkg.dec
+  Platform/Hisilicon/HiKey/HiKey.dec
+
+[Depex]
+  TRUE
diff --git a/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c b/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
new file mode 100644
index 000000000000..4d651746d590
--- /dev/null
+++ b/Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.c
@@ -0,0 +1,280 @@
+/** @file
+*
+*  Copyright (c) 2018, 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;
+  }
+  /* 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;
+
+  Status = mGpio->Get (mGpio, USB_ID_DET_GPIO2_5, &GpioId);
+  ASSERT_EFI_ERROR (Status);
+  Status = mGpio->Get (mGpio, USB_VBUS_DET_GPIO2_6, &GpioVbus);
+  ASSERT_EFI_ERROR (Status);
+
+  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, PERIPH_CLKEN0_USBOTG);
+  do {
+       Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CLKSTAT0);
+  } while ((Value & PERIPH_CLKEN0_USBOTG) == 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 (HiKeyGetUsbMode () != Mode) {
+    return EFI_INVALID_PARAMETER;
+  }
+  //
+  // If Mode = 1, USB in Device Mode
+  // If Mode = 0, USB in Host Mode
+  //
+  if (Mode == USB_DEVICE_MODE) {
+    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 {
+    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);
+    /*
+     * Set the USB phy timing with tuned value that shows an eye
+     * pattern on oscillator.
+     */
+    MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL8, 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;
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH edk-platforms v1 3/4] Platform/HiKey: add fastboot platform driver
  2018-08-21 11:35 [PATCH edk-platforms v1 0/4] enable usb driver on HiKey Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 1/4] Platform/HiKey: add more register definitions Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 2/4] Platform/HiKey: add usb platform driver Haojian Zhuang
@ 2018-08-21 11:35 ` Haojian Zhuang
  2018-08-21 11:35 ` [PATCH edk-platforms v1 4/4] Platform/HiKey: enable usb driver Haojian Zhuang
  3 siblings, 0 replies; 5+ messages in thread
From: Haojian Zhuang @ 2018-08-21 11:35 UTC (permalink / raw)
  To: edk2-devel

Implement Android Fastboot protocol on HiKey platform.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf |  61 ++
 Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c   | 630 ++++++++++++++++++++
 2 files changed, 691 insertions(+)

diff --git a/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf b/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
new file mode 100644
index 000000000000..2f2f1c4cb0a0
--- /dev/null
+++ b/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
@@ -0,0 +1,61 @@
+#/** @file
+#
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) 2018, 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                      = HiKeyFastbootDxe
+  FILE_GUID                      = 8e335c38-c4e1-494e-8011-37a858d9763d
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = HiKeyFastbootPlatformEntryPoint
+
+[Sources.common]
+  HiKeyFastbootDxe.c
+
+[LibraryClasses]
+  BaseLib
+  BaseMemoryLib
+  CacheMaintenanceLib
+  DebugLib
+  DevicePathLib
+  IoLib
+  MemoryAllocationLib
+  PcdLib
+  UefiBootServicesTableLib
+  UefiRuntimeServicesTableLib
+  UefiDriverEntryPoint
+  UsbSerialNumberLib
+  TimerLib
+
+[Protocols]
+  gAndroidFastbootPlatformProtocolGuid
+  gEfiBlockIoProtocolGuid
+  gEfiDiskIoProtocolGuid
+  gEfiEraseBlockProtocolGuid
+  gEfiSimpleTextOutProtocolGuid
+
+[Packages]
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  Platform/Hisilicon/HiKey/HiKey.dec
+  Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.dec
+
+[Pcd]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor
+  gHiKeyTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath
+  gHiKeyTokenSpaceGuid.PcdArmFastbootFlashLimit
diff --git a/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c b/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c
new file mode 100644
index 000000000000..f5a9c53b6a23
--- /dev/null
+++ b/Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.c
@@ -0,0 +1,630 @@
+/** @file
+
+  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>
+  Copyright (c) 2018, 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.
+
+**/
+
+/*
+  Implementation of the Android Fastboot Platform protocol, to be used by the
+  Fastboot UEFI application, for Hisilicon HiKey platform.
+*/
+
+#include <Protocol/AndroidFastbootPlatform.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DiskIo.h>
+#include <Protocol/EraseBlock.h>
+#include <Protocol/SimpleTextOut.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/CacheMaintenanceLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/UsbSerialNumberLib.h>
+#include <Library/PrintLib.h>
+#include <Library/TimerLib.h>
+
+#define PARTITION_NAME_MAX_LENGTH (72/2)
+
+#define SERIAL_NUMBER_LBA                1024
+#define RANDOM_MAX                       0x7FFFFFFFFFFFFFFF
+#define RANDOM_MAGIC                     0x9A4DBEAF
+
+#define ADB_REBOOT_ADDRESS               0x05F01000
+#define ADB_REBOOT_BOOTLOADER            0x77665500
+
+#define MMC_BLOCK_SIZE                   512
+#define HIKEY_ERASE_SIZE                 4096
+
+typedef struct _FASTBOOT_PARTITION_LIST {
+  LIST_ENTRY  Link;
+  CHAR16      PartitionName[PARTITION_NAME_MAX_LENGTH];
+  EFI_LBA     StartingLBA;
+  EFI_LBA     EndingLBA;
+} FASTBOOT_PARTITION_LIST;
+
+STATIC LIST_ENTRY                       mPartitionListHead;
+STATIC EFI_HANDLE                       mFlashHandle;
+STATIC EFI_BLOCK_IO_PROTOCOL           *mFlashBlockIo;
+STATIC EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *mTextOut;
+
+/*
+  Helper to free the partition list
+*/
+STATIC
+VOID
+FreePartitionList (
+  VOID
+  )
+{
+  FASTBOOT_PARTITION_LIST *Entry;
+  FASTBOOT_PARTITION_LIST *NextEntry;
+
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    NextEntry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+
+    RemoveEntryList (&Entry->Link);
+    FreePool (Entry);
+
+    Entry = NextEntry;
+  }
+}
+
+/*
+  Read the PartitionName fields from the GPT partition entries, putting them
+  into an allocated array that should later be freed.
+*/
+STATIC
+EFI_STATUS
+ReadPartitionEntries (
+  IN  EFI_BLOCK_IO_PROTOCOL *BlockIo,
+  OUT EFI_PARTITION_ENTRY  **PartitionEntries,
+  OUT UINTN                 *PartitionNumbers
+  )
+{
+  EFI_STATUS                  Status;
+  UINT32                      MediaId;
+  UINTN                       BlockSize;
+  UINTN                       PageCount;
+  UINTN                       Count, EndLBA;
+  EFI_PARTITION_TABLE_HEADER *GptHeader;
+  EFI_PARTITION_ENTRY        *Entry;
+  VOID                       *Buffer;
+
+  if ((PartitionEntries == NULL) || (PartitionNumbers == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  MediaId = BlockIo->Media->MediaId;
+  BlockSize = BlockIo->Media->BlockSize;
+
+  //
+  // Read size of Partition entry and number of entries from GPT header
+  //
+
+  PageCount = EFI_SIZE_TO_PAGES (34 * BlockSize);
+  Buffer = AllocatePages (PageCount);
+  if (Buffer == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Status = BlockIo->ReadBlocks (BlockIo, MediaId, 0, PageCount * EFI_PAGE_SIZE, Buffer);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  GptHeader = (EFI_PARTITION_TABLE_HEADER *)(Buffer + BlockSize);
+
+  // Check there is a GPT on the media
+  if (GptHeader->Header.Signature != EFI_PTAB_HEADER_ID ||
+      GptHeader->MyLBA != 1) {
+    DEBUG ((EFI_D_ERROR,
+      "Fastboot platform: No GPT on flash. "
+      "Fastboot on HiKey does not support MBR.\n"
+      ));
+    return EFI_DEVICE_ERROR;
+  }
+
+  Entry = (EFI_PARTITION_ENTRY *)(Buffer + (2 * BlockSize));
+  EndLBA = GptHeader->FirstUsableLBA - 1;
+  Count = 0;
+  while (1) {
+    if ((Entry->StartingLBA > EndLBA) && (Entry->EndingLBA <= GptHeader->LastUsableLBA)) {
+      Count++;
+      EndLBA = Entry->EndingLBA;
+      Entry++;
+    } else {
+      break;
+    }
+  }
+  if (Count == 0) {
+    return EFI_INVALID_PARAMETER;
+  }
+  if (Count > GptHeader->NumberOfPartitionEntries) {
+    Count = GptHeader->NumberOfPartitionEntries;
+  }
+
+  *PartitionEntries = (EFI_PARTITION_ENTRY *)((UINTN)Buffer + (2 * BlockSize));
+  *PartitionNumbers = Count;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LoadPtable (
+  VOID
+  )
+{
+  EFI_STATUS                          Status;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
+  EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePathDup;
+  UINTN                               PartitionNumbers = 0;
+  UINTN                               LoopIndex;
+  EFI_PARTITION_ENTRY                *PartitionEntries = NULL;
+  FASTBOOT_PARTITION_LIST            *Entry;
+
+  InitializeListHead (&mPartitionListHead);
+
+  Status = gBS->LocateProtocol (&gEfiSimpleTextOutProtocolGuid, NULL, (VOID **) &mTextOut);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR,
+      "Fastboot platform: Couldn't open Text Output Protocol: %r\n", Status
+      ));
+    return Status;
+  }
+
+  //
+  // Get EFI_HANDLES for all the partitions on the block devices pointed to by
+  // PcdFastbootFlashDevicePath, also saving their GPT partition labels.
+  // There's no way to find all of a device's children, so we get every handle
+  // in the system supporting EFI_BLOCK_IO_PROTOCOL and then filter out ones
+  // that don't represent partitions on the flash device.
+  //
+  FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
+
+  // Create another device path pointer because LocateDevicePath will modify it.
+  FlashDevicePathDup = FlashDevicePath;
+  Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePathDup, &mFlashHandle);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
+    // Failing to locate partitions should not prevent to do other Android FastBoot actions
+    return EFI_SUCCESS;
+  }
+
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiBlockIoProtocolGuid,
+                  (VOID **) &mFlashBlockIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fastboot platform: Couldn't open Android NVM device (status: %r)\n", Status));
+    return EFI_DEVICE_ERROR;
+  }
+
+  // Read the GPT partition entry array into memory so we can get the partition names
+  Status = ReadPartitionEntries (mFlashBlockIo, &PartitionEntries, &PartitionNumbers);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Warning: Failed to read partitions from Android NVM device (status: %r)\n", Status));
+    // Failing to locate partitions should not prevent to do other Android FastBoot actions
+    return EFI_SUCCESS;
+  }
+  for (LoopIndex = 0; LoopIndex < PartitionNumbers; LoopIndex++) {
+    // Create entry
+    Entry = AllocatePool (sizeof (FASTBOOT_PARTITION_LIST));
+    if (Entry == NULL) {
+      Status = EFI_BUFFER_TOO_SMALL;
+      FreePartitionList ();
+      goto Exit;
+    }
+    StrnCpy (
+      Entry->PartitionName,
+      PartitionEntries[LoopIndex].PartitionName,
+      PARTITION_NAME_MAX_LENGTH
+      );
+    Entry->StartingLBA = PartitionEntries[LoopIndex].StartingLBA;
+    Entry->EndingLBA = PartitionEntries[LoopIndex].EndingLBA;
+    InsertTailList (&mPartitionListHead, &Entry->Link);
+  }
+Exit:
+  FreePages (
+    (VOID *)((UINTN)PartitionEntries - (2 * mFlashBlockIo->Media->BlockSize)),
+    EFI_SIZE_TO_PAGES (34 * mFlashBlockIo->Media->BlockSize)
+    );
+  return Status;
+}
+
+/*
+  Initialise: Open the Android NVM device and find the partitions on it. Save them in
+  a list along with the "PartitionName" fields for their GPT entries.
+  We will use these partition names as the key in
+  HiKeyFastbootPlatformFlashPartition.
+*/
+EFI_STATUS
+HiKeyFastbootPlatformInit (
+  VOID
+  )
+{
+  return LoadPtable ();
+}
+
+VOID
+HiKeyFastbootPlatformUnInit (
+  VOID
+  )
+{
+  FreePartitionList ();
+}
+
+EFI_STATUS
+HiKeyFlashPtable (
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS               Status;
+  EFI_DISK_IO_PROTOCOL    *DiskIo;
+  UINT32                   MediaId;
+  VOID                    *Buffer;
+  UINT32                   EntrySize, EntryOffset;
+  UINTN                    BlockSize;
+
+  MediaId = mFlashBlockIo->Media->MediaId;
+  BlockSize = mFlashBlockIo->Media->BlockSize;
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Buffer = Image;
+  if (AsciiStrnCmp (Buffer, "ENTRYHDR", 8) != 0) {
+    DEBUG ((EFI_D_ERROR, "It should be raw ptable image\n"));
+    Status = DiskIo->WriteDisk (DiskIo, MediaId, 0, Size, Image);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  } else {
+    /* ptable with entry header */
+    Buffer += 8;
+    if (AsciiStrnCmp (Buffer, "primary", 7) != 0) {
+      DEBUG ((EFI_D_ERROR, "unknown ptable imag\n"));
+      return EFI_UNSUPPORTED;
+    }
+    Buffer += 8;
+    EntryOffset = *(UINT32 *)Buffer * BlockSize;
+    Buffer += 4;
+    EntrySize = *(UINT32 *)Buffer * BlockSize;
+    if ((EntrySize + BlockSize) > Size) {
+      DEBUG ((DEBUG_ERROR, "Entry size doesn't match\n"));
+      return EFI_UNSUPPORTED;
+    }
+    Buffer = Image + BlockSize;
+    Status = DiskIo->WriteDisk (DiskIo, MediaId, EntryOffset, EntrySize, Buffer);
+    if (EFI_ERROR (Status)) {
+      return Status;
+    }
+  }
+  FreePartitionList ();
+  Status = LoadPtable ();
+  return Status;
+}
+
+EFI_STATUS
+HiKeyFastbootPlatformFlashPartition (
+  IN CHAR8  *PartitionName,
+  IN UINTN   Size,
+  IN VOID   *Image
+  )
+{
+  EFI_STATUS               Status;
+  UINTN                    PartitionSize;
+  FASTBOOT_PARTITION_LIST *Entry;
+  CHAR16                   PartitionNameUnicode[60];
+  BOOLEAN                  PartitionFound;
+  EFI_DISK_IO_PROTOCOL    *DiskIo;
+  UINTN                    BlockSize;
+
+  // Support the pseudo partition name, such as "ptable".
+  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+    return HiKeyFlashPtable (Size, Image);
+  }
+
+  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+  PartitionFound = FALSE;
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    // Search the partition list for the partition named by PartitionName
+    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+      PartitionFound = TRUE;
+      break;
+    }
+
+   Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+  }
+  if (!PartitionFound) {
+    return EFI_NOT_FOUND;
+  }
+
+  // Check image will fit on device
+  BlockSize = mFlashBlockIo->Media->BlockSize;
+  PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * BlockSize;
+  if (PartitionSize < Size) {
+    DEBUG ((DEBUG_ERROR, "Partition not big enough.\n"));
+    DEBUG ((DEBUG_ERROR, "Partition Size:\t%ld\nImage Size:\t%ld\n", PartitionSize, Size));
+
+    return EFI_VOLUME_FULL;
+  }
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiDiskIoProtocolGuid,
+                  (VOID **) &DiskIo,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  Status = DiskIo->WriteDisk (
+                     DiskIo,
+                     mFlashBlockIo->Media->MediaId,
+                     Entry->StartingLBA * BlockSize,
+                     Size,
+                     Image
+                     );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Failed to write %d bytes into 0x%x, Status:%r\n", Size, Entry->StartingLBA * BlockSize, Status));
+    return Status;
+  }
+
+  mFlashBlockIo->FlushBlocks(mFlashBlockIo);
+  MicroSecondDelay (50000);
+
+  return Status;
+}
+
+EFI_STATUS
+HiKeyErasePtable (
+  VOID
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ERASE_BLOCK_PROTOCOL   *EraseBlockProtocol;
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiEraseBlockProtocolGuid,
+                  (VOID **) &EraseBlockProtocol,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "Fastboot platform: could not open Erase Block IO: %r\n", Status));
+    return EFI_DEVICE_ERROR;
+  }
+  Status = EraseBlockProtocol->EraseBlocks (
+                                 EraseBlockProtocol,
+                                 mFlashBlockIo->Media->MediaId,
+                                 0,
+                                 NULL,
+                                 34 * mFlashBlockIo->Media->BlockSize
+                                 );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  FreePartitionList ();
+  return Status;
+}
+
+EFI_STATUS
+HiKeyFastbootPlatformErasePartition (
+  IN CHAR8 *PartitionName
+  )
+{
+  EFI_STATUS                  Status;
+  EFI_ERASE_BLOCK_PROTOCOL   *EraseBlockProtocol;
+  UINTN                       Size;
+  BOOLEAN                     PartitionFound;
+  CHAR16                      PartitionNameUnicode[60];
+  FASTBOOT_PARTITION_LIST    *Entry;
+
+  AsciiStrToUnicodeStr (PartitionName, PartitionNameUnicode);
+
+  // Support the pseudo partition name, such as "ptable".
+  if (AsciiStrCmp (PartitionName, "ptable") == 0) {
+    return HiKeyErasePtable ();
+  }
+
+  PartitionFound = FALSE;
+  Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&mPartitionListHead);
+  while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+    // Search the partition list for the partition named by PartitionName
+    if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+      PartitionFound = TRUE;
+      break;
+    }
+    Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &Entry->Link);
+  }
+  if (!PartitionFound) {
+    return EFI_NOT_FOUND;
+  }
+
+  Status = gBS->OpenProtocol (
+                  mFlashHandle,
+                  &gEfiEraseBlockProtocolGuid,
+                  (VOID **) &EraseBlockProtocol,
+                  gImageHandle,
+                  NULL,
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
+                  );
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+  Size = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+  Status = EraseBlockProtocol->EraseBlocks (
+                                 EraseBlockProtocol,
+                                 mFlashBlockIo->Media->MediaId,
+                                 Entry->StartingLBA,
+                                 NULL,
+                                 Size
+                                 );
+  return Status;
+}
+
+EFI_STATUS
+HiKeyFastbootPlatformGetVar (
+  IN  CHAR8   *Name,
+  OUT CHAR8   *Value
+  )
+{
+  EFI_STATUS               Status;
+  UINT64                   PartitionSize;
+  FASTBOOT_PARTITION_LIST *Entry;
+  CHAR16                   PartitionNameUnicode[60];
+  BOOLEAN                  PartitionFound;
+  CHAR16                   UnicodeSN[SERIAL_NUMBER_SIZE];
+
+  if (!AsciiStrCmp (Name, "max-download-size")) {
+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdArmFastbootFlashLimit));
+  } else if (!AsciiStrCmp (Name, "product")) {
+    AsciiStrCpy (Value, FixedPcdGetPtr (PcdFirmwareVendor));
+  } else if (!AsciiStrCmp (Name, "serialno")) {
+    Status = LoadSNFromBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+    if (EFI_ERROR (Status)) {
+      *Value = '\0';
+      return Status;
+    }
+    UnicodeStrToAsciiStr (UnicodeSN, Value);
+  } else if ( !AsciiStrnCmp (Name, "partition-size", 14)) {
+    AsciiStrToUnicodeStr ((Name + 15), PartitionNameUnicode);
+    PartitionFound = FALSE;
+    Entry = (FASTBOOT_PARTITION_LIST *) GetFirstNode (&(mPartitionListHead));
+    while (!IsNull (&mPartitionListHead, &Entry->Link)) {
+      // Search the partition list for the partition named by PartitionName
+      if (StrCmp (Entry->PartitionName, PartitionNameUnicode) == 0) {
+        PartitionFound = TRUE;
+        break;
+      }
+
+     Entry = (FASTBOOT_PARTITION_LIST *) GetNextNode (&mPartitionListHead, &(Entry)->Link);
+    }
+    if (!PartitionFound) {
+      *Value = '\0';
+      return EFI_NOT_FOUND;
+    }
+
+    PartitionSize = (Entry->EndingLBA - Entry->StartingLBA + 1) * mFlashBlockIo->Media->BlockSize;
+    DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-size:%a 0X%llx\n", Name, PartitionSize));
+    AsciiSPrint (Value, 12, "0x%llx", PartitionSize);
+  } else if ( !AsciiStrnCmp (Name, "partition-type", 14)) {
+      DEBUG ((DEBUG_ERROR, "Fastboot platform: check for partition-type:%a\n", (Name + 15)));
+    if ( !AsciiStrnCmp  ( (Name + 15) , "system", 6) || !AsciiStrnCmp  ( (Name + 15) , "userdata", 8)
+            || !AsciiStrnCmp  ( (Name + 15) , "cache", 5)
+            || !AsciiStrnCmp  ( (Name + 15) , "vendor", 6)) {
+      AsciiStrCpy (Value, "ext4");
+    } else {
+      AsciiStrCpy (Value, "raw");
+    }
+  } else if ( !AsciiStrCmp (Name, "erase-block-size")) {
+    AsciiSPrint (Value, 12, "0x%llx", HIKEY_ERASE_SIZE);
+  } else if ( !AsciiStrCmp (Name, "logical-block-size")) {
+    AsciiSPrint (Value, 12, "0x%llx", HIKEY_ERASE_SIZE);
+  } else {
+    *Value = '\0';
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HiKeyFastbootPlatformOemCommand (
+  IN  CHAR8   *Command
+  )
+{
+  EFI_STATUS   Status;
+  CHAR16       UnicodeSN[SERIAL_NUMBER_SIZE];
+  UINTN        Size;
+
+  Size = AsciiStrLen ("serialno");
+  if (AsciiStrCmp (Command, "Demonstrate") == 0) {
+    DEBUG ((DEBUG_ERROR, "ARM OEM Fastboot command 'Demonstrate' received.\n"));
+    return EFI_SUCCESS;
+  } else if (AsciiStrnCmp (Command, "serialno", Size) == 0) {
+    while (*(Command + Size) == ' ') {
+      Size++;
+    }
+    if (AsciiStrnCmp (Command + Size, "set", AsciiStrLen ("set")) == 0) {
+      Size += AsciiStrLen ("set");
+      while (*(Command + Size) == ' ') {
+        Size++;
+      }
+      Status = AssignUsbSN (Command + Size, UnicodeSN);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Failed to set USB Serial Number.\n"));
+        return Status;
+      }
+    } else {
+      Status = GenerateUsbSN (UnicodeSN);
+      if (EFI_ERROR (Status)) {
+        DEBUG ((DEBUG_ERROR, "Failed to generate USB Serial Number.\n"));
+        return Status;
+      }
+    }
+    Status = StoreSNToBlock (mFlashHandle, SERIAL_NUMBER_LBA, UnicodeSN);
+    return Status;
+  } else if (AsciiStrCmp (Command, "reboot-bootloader") == 0) {
+    MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_BOOTLOADER);
+    WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
+    return EFI_SUCCESS;
+  } else {
+    DEBUG ((DEBUG_ERROR,
+      "HiKey: Unrecognised Fastboot OEM command: %s\n",
+      Command
+      ));
+    return EFI_NOT_FOUND;
+  }
+}
+
+FASTBOOT_PLATFORM_PROTOCOL mPlatformProtocol = {
+  HiKeyFastbootPlatformInit,
+  HiKeyFastbootPlatformUnInit,
+  HiKeyFastbootPlatformFlashPartition,
+  HiKeyFastbootPlatformErasePartition,
+  HiKeyFastbootPlatformGetVar,
+  HiKeyFastbootPlatformOemCommand
+};
+
+EFI_STATUS
+EFIAPI
+HiKeyFastbootPlatformEntryPoint (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  return gBS->InstallProtocolInterface (
+                &ImageHandle,
+                &gAndroidFastbootPlatformProtocolGuid,
+                EFI_NATIVE_INTERFACE,
+                &mPlatformProtocol
+                );
+}
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH edk-platforms v1 4/4] Platform/HiKey: enable usb driver
  2018-08-21 11:35 [PATCH edk-platforms v1 0/4] enable usb driver on HiKey Haojian Zhuang
                   ` (2 preceding siblings ...)
  2018-08-21 11:35 ` [PATCH edk-platforms v1 3/4] Platform/HiKey: add fastboot " Haojian Zhuang
@ 2018-08-21 11:35 ` Haojian Zhuang
  3 siblings, 0 replies; 5+ messages in thread
From: Haojian Zhuang @ 2018-08-21 11:35 UTC (permalink / raw)
  To: edk2-devel

Enable Designware USB 2.0 device driver on HiKey platform. It's
used in Android Fastboot App.

Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Haojian Zhuang <haojian.zhuang@linaro.org>
---
 Platform/Hisilicon/HiKey/HiKey.dec |  2 ++
 Platform/Hisilicon/HiKey/HiKey.dsc | 13 +++++++++++++
 Platform/Hisilicon/HiKey/HiKey.fdf |  3 +++
 3 files changed, 18 insertions(+)

diff --git a/Platform/Hisilicon/HiKey/HiKey.dec b/Platform/Hisilicon/HiKey/HiKey.dec
index d5de1a165910..ed9eab7ff2a9 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dec
+++ b/Platform/Hisilicon/HiKey/HiKey.dec
@@ -36,3 +36,5 @@ [PcdsFixedAtBuild.common]
   gHiKeyTokenSpaceGuid.PcdAndroidBootFile|{ 0x36, 0x8b, 0x73, 0x3a, 0xc5, 0xb9, 0x63, 0x47, 0xab, 0xbd, 0x6c, 0xbd, 0x4b, 0x25, 0xf9, 0xff }|VOID*|0x00000002
   gHiKeyTokenSpaceGuid.PcdAndroidFastbootFile|{ 0x2a, 0x50, 0x88, 0x95, 0x70, 0x53, 0xe3, 0x11, 0x86, 0x31, 0xd7, 0xc5, 0x95, 0x13, 0x64, 0xc8 }|VOID*|0x00000003
   gHiKeyTokenSpaceGuid.PcdSdBootDevicePath|L""|VOID*|0x00000004
+  gHiKeyTokenSpaceGuid.PcdAndroidFastbootNvmDevicePath|L""|VOID*|0x00000005
+  gHiKeyTokenSpaceGuid.PcdArmFastbootFlashLimit|L""|VOID*|0x00000006
diff --git a/Platform/Hisilicon/HiKey/HiKey.dsc b/Platform/Hisilicon/HiKey/HiKey.dsc
index 4b5b73c15afe..93b981767681 100644
--- a/Platform/Hisilicon/HiKey/HiKey.dsc
+++ b/Platform/Hisilicon/HiKey/HiKey.dsc
@@ -53,12 +53,16 @@ [LibraryClasses.common]
   # USB Requirements
   UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
 
+  UsbSerialNumberLib|Platform/Hisilicon/Library/UsbSerialNumberLib/UsbSerialNumberLib.inf
+
   # Network Libraries
   NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
   DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
   IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
   UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
 
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+
 [LibraryClasses.common.SEC]
   PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
   ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
@@ -85,6 +89,7 @@ [PcdsFeatureFlag.common]
 [PcdsFixedAtBuild.common]
   gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
 
+  gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor|"hikey"
   gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString|L"Alpha"
 
   # System Memory (1GB)
@@ -126,6 +131,11 @@ [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdMetronomeTickPeriod|1000
 
   #
+  # DW USB controller
+  #
+  gDwUsbDxeTokenSpaceGuid.PcdDwUsbDxeBaseAddress|0xF72C0000
+
+  #
   #
   # Fastboot
   #
@@ -222,6 +232,9 @@ [Components.common]
   #
   # USB Peripheral Support
   #
+  Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
+  EmbeddedPkg/Drivers/DwUsbDxe/DwUsbDxe.inf
+  Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
   EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
 
   #
diff --git a/Platform/Hisilicon/HiKey/HiKey.fdf b/Platform/Hisilicon/HiKey/HiKey.fdf
index 89d3e9280ff6..aedf71667903 100644
--- a/Platform/Hisilicon/HiKey/HiKey.fdf
+++ b/Platform/Hisilicon/HiKey/HiKey.fdf
@@ -152,6 +152,9 @@ [FV.FvMain]
   #
   # USB Peripheral Support
   #
+  INF Platform/Hisilicon/HiKey/HiKeyUsbDxe/HiKeyUsbDxe.inf
+  INF EmbeddedPkg/Drivers/DwUsbDxe/DwUsbDxe.inf
+  INF Platform/Hisilicon/HiKey/HiKeyFastbootDxe/HiKeyFastbootDxe.inf
   INF EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf
 
   #
-- 
2.7.4



^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-08-21 11:35 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-08-21 11:35 [PATCH edk-platforms v1 0/4] enable usb driver on HiKey Haojian Zhuang
2018-08-21 11:35 ` [PATCH edk-platforms v1 1/4] Platform/HiKey: add more register definitions Haojian Zhuang
2018-08-21 11:35 ` [PATCH edk-platforms v1 2/4] Platform/HiKey: add usb platform driver Haojian Zhuang
2018-08-21 11:35 ` [PATCH edk-platforms v1 3/4] Platform/HiKey: add fastboot " Haojian Zhuang
2018-08-21 11:35 ` [PATCH edk-platforms v1 4/4] Platform/HiKey: enable usb driver Haojian Zhuang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox