Home | History | Annotate | Download | only in HiKeyUsbDxe
      1 /** @file
      2 *
      3 *  Copyright (c) 2015-2017, Linaro. All rights reserved.
      4 *
      5 *  This program and the accompanying materials
      6 *  are licensed and made available under the terms and conditions of the BSD License
      7 *  which accompanies this distribution.  The full text of the license may be found at
      8 *  http://opensource.org/licenses/bsd-license.php
      9 *
     10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 *
     13 **/
     14 
     15 #include <Library/BaseMemoryLib.h>
     16 #include <Library/DebugLib.h>
     17 #include <Library/DevicePathLib.h>
     18 #include <Library/IoLib.h>
     19 #include <Library/TimerLib.h>
     20 #include <Library/UefiBootServicesTableLib.h>
     21 #include <Library/UefiLib.h>
     22 #include <Library/UefiRuntimeServicesTableLib.h>
     23 #include <Library/UsbSerialNumberLib.h>
     24 
     25 #include <Protocol/EmbeddedGpio.h>
     26 #include <Protocol/DwUsb.h>
     27 
     28 #include <Hi6220.h>
     29 
     30 
     31 #define USB_SEL_GPIO0_3          3     // GPIO 0_3
     32 #define USB_5V_HUB_EN            7     // GPIO 0_7
     33 #define USB_ID_DET_GPIO2_5       21    // GPIO 2_5
     34 #define USB_VBUS_DET_GPIO2_6     22    // GPIO 2_6
     35 
     36 // Jumper on pin5-6 of J15 determines whether boot to fastboot
     37 #define DETECT_J15_FASTBOOT      24    // GPIO 3_0
     38 
     39 #define SERIAL_NUMBER_LBA        1024
     40 
     41 STATIC EMBEDDED_GPIO *mGpio;
     42 
     43 STATIC
     44 VOID
     45 HiKeyDetectUsbModeInit (
     46   IN VOID
     47   )
     48 {
     49   EFI_STATUS     Status;
     50 
     51   /* set pullup on both GPIO2_5 & GPIO2_6. It's required for inupt. */
     52   MmioWrite32 (0xf8001864, 1);
     53   MmioWrite32 (0xf8001868, 1);
     54 
     55   Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&mGpio);
     56   ASSERT_EFI_ERROR (Status);
     57   Status = mGpio->Set (mGpio, USB_SEL_GPIO0_3, GPIO_MODE_OUTPUT_0);
     58   ASSERT_EFI_ERROR (Status);
     59   Status = mGpio->Set (mGpio, USB_5V_HUB_EN, GPIO_MODE_OUTPUT_0);
     60   ASSERT_EFI_ERROR (Status);
     61   MicroSecondDelay (1000);
     62 
     63   Status = mGpio->Set (mGpio, USB_ID_DET_GPIO2_5, GPIO_MODE_INPUT);
     64   ASSERT_EFI_ERROR (Status);
     65   Status = mGpio->Set (mGpio, USB_VBUS_DET_GPIO2_6, GPIO_MODE_INPUT);
     66   ASSERT_EFI_ERROR (Status);
     67 }
     68 
     69 UINTN
     70 HiKeyGetUsbMode (
     71   IN VOID
     72   )
     73 {
     74 #if 0
     75   EFI_STATUS     Status;
     76   UINTN          GpioId, GpioVbus;
     77   UINTN          Value;
     78 
     79   Status = mGpio->Get (mGpio, USB_ID_DET_GPIO2_5, &Value);
     80   ASSERT_EFI_ERROR (Status);
     81   GpioId = Value;
     82   Status = mGpio->Get (mGpio, USB_VBUS_DET_GPIO2_6, &Value);
     83   ASSERT_EFI_ERROR (Status);
     84   GpioVbus = Value;
     85 
     86 DEBUG ((DEBUG_ERROR, "#%a, %d, GpioId:%d, GpioVbus:%d\n", __func__, __LINE__, GpioId, GpioVbus));
     87   if ((GpioId == 1) && (GpioVbus == 0)) {
     88     return USB_DEVICE_MODE;
     89   } else if ((GpioId == 0) && (GpioVbus == 1)) {
     90     return USB_CABLE_NOT_ATTACHED;
     91   }
     92   return USB_HOST_MODE;
     93 #else
     94   return USB_DEVICE_MODE;
     95 #endif
     96 }
     97 
     98 EFI_STATUS
     99 HiKeyUsbPhyInit (
    100   IN UINT8        Mode
    101   )
    102 {
    103   UINTN         Value;
    104   UINT32        Data;
    105 
    106   HiKeyDetectUsbModeInit ();
    107 
    108   //setup clock
    109   MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN0, BIT4);
    110   do {
    111        Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CLKSTAT0);
    112   } while ((Value & BIT4) == 0);
    113 
    114   //setup phy
    115   Data = RST0_USBOTG_BUS | RST0_POR_PICOPHY |
    116            RST0_USBOTG | RST0_USBOTG_32K;
    117   MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, Data);
    118   do {
    119     Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT0);
    120     Value &= Data;
    121   } while (Value);
    122 
    123   Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4);
    124   Value &= ~(CTRL4_PICO_SIDDQ | CTRL4_FPGA_EXT_PHY_SEL |
    125              CTRL4_OTG_PHY_SEL);
    126   Value |=  CTRL4_PICO_VBUSVLDEXT | CTRL4_PICO_VBUSVLDEXTSEL;
    127   MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL4, Value);
    128   MicroSecondDelay (1000);
    129 
    130   //If Mode = 1, USB in Device Mode
    131   //If Mode = 0, USB in Host Mode
    132   if (Mode == USB_DEVICE_MODE) {
    133     if (HiKeyGetUsbMode () == USB_DEVICE_MODE) {
    134       DEBUG ((DEBUG_ERROR, "usb work as device mode.\n"));
    135     } else {
    136       return EFI_INVALID_PARAMETER;
    137     }
    138 
    139      Value = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
    140      Value &= ~CTRL5_PICOPHY_BC_MODE;
    141      MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Value);
    142      MicroSecondDelay (20000);
    143   } else {
    144     if (HiKeyGetUsbMode () == USB_HOST_MODE) {
    145       DEBUG ((DEBUG_ERROR, "usb work as host mode.\n"));
    146     } else {
    147       return EFI_INVALID_PARAMETER;
    148     }
    149 
    150     /*CTRL5*/
    151     Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5);
    152     Data &= ~CTRL5_PICOPHY_BC_MODE;
    153     Data |= CTRL5_USBOTG_RES_SEL | CTRL5_PICOPHY_ACAENB |
    154             CTRL5_PICOPHY_VDATDETENB | CTRL5_PICOPHY_DCDENB;
    155     MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CTRL5, Data);
    156     MicroSecondDelay (20000);
    157     MmioWrite32 (PERI_CTRL_BASE + 0x018, 0x70533483); //EYE_PATTERN
    158 
    159     MicroSecondDelay (5000);
    160   }
    161 
    162   return EFI_SUCCESS;
    163 }
    164 
    165 EFI_STATUS
    166 EFIAPI
    167 HiKeyUsbGetLang (
    168   OUT CHAR16            *Lang,
    169   OUT UINT8             *Length
    170   )
    171 {
    172   if ((Lang == NULL) || (Length == NULL)) {
    173     return EFI_INVALID_PARAMETER;
    174   }
    175   Lang[0] = 0x409;
    176   *Length = sizeof (CHAR16);
    177   return EFI_SUCCESS;
    178 }
    179 
    180 EFI_STATUS
    181 EFIAPI
    182 HiKeyUsbGetManuFacturer (
    183   OUT CHAR16            *ManuFacturer,
    184   OUT UINT8             *Length
    185   )
    186 {
    187   UINTN                  VariableSize;
    188   CHAR16                 DataUnicode[MANU_FACTURER_STRING_LENGTH];
    189 
    190   if ((ManuFacturer == NULL) || (Length == NULL)) {
    191     return EFI_INVALID_PARAMETER;
    192   }
    193   VariableSize = MANU_FACTURER_STRING_LENGTH * sizeof (CHAR16);
    194   ZeroMem (DataUnicode, MANU_FACTURER_STRING_LENGTH * sizeof(CHAR16));
    195   StrCpy (DataUnicode, L"96Boards");
    196   CopyMem (ManuFacturer, DataUnicode, VariableSize);
    197   *Length = VariableSize;
    198   return EFI_SUCCESS;
    199 }
    200 
    201 EFI_STATUS
    202 EFIAPI
    203 HiKeyUsbGetProduct (
    204   OUT CHAR16            *Product,
    205   OUT UINT8             *Length
    206   )
    207 {
    208   UINTN                  VariableSize;
    209   CHAR16                 DataUnicode[PRODUCT_STRING_LENGTH];
    210 
    211   if ((Product == NULL) || (Length == NULL)) {
    212     return EFI_INVALID_PARAMETER;
    213   }
    214   VariableSize = PRODUCT_STRING_LENGTH * sizeof (CHAR16);
    215   ZeroMem (DataUnicode, PRODUCT_STRING_LENGTH * sizeof(CHAR16));
    216   StrCpy (DataUnicode, L"HiKey");
    217   CopyMem (Product, DataUnicode, VariableSize);
    218   *Length = VariableSize;
    219   return EFI_SUCCESS;
    220 }
    221 
    222 EFI_STATUS
    223 EFIAPI
    224 HiKeyUsbGetSerialNo (
    225   OUT CHAR16            *SerialNo,
    226   OUT UINT8             *Length
    227   )
    228 {
    229   EFI_STATUS                          Status;
    230   EFI_DEVICE_PATH_PROTOCOL           *FlashDevicePath;
    231   EFI_HANDLE                          FlashHandle;
    232 
    233   FlashDevicePath = ConvertTextToDevicePath ((CHAR16*)FixedPcdGetPtr (PcdAndroidFastbootNvmDevicePath));
    234   Status = gBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &FlashDevicePath, &FlashHandle);
    235   if (EFI_ERROR (Status)) {
    236     DEBUG ((DEBUG_ERROR, "Warning: Couldn't locate Android NVM device (status: %r)\n", Status));
    237     // Failing to locate partitions should not prevent to do other Android FastBoot actions
    238     return EFI_SUCCESS;
    239   }
    240 
    241   if ((SerialNo == NULL) || (Length == NULL)) {
    242     return EFI_INVALID_PARAMETER;
    243   }
    244   Status = LoadSNFromBlock (FlashHandle, SERIAL_NUMBER_LBA, SerialNo);
    245   *Length = StrSize (SerialNo);
    246   return Status;
    247 }
    248 
    249 DW_USB_PROTOCOL mDwUsbDevice = {
    250   HiKeyUsbGetLang,
    251   HiKeyUsbGetManuFacturer,
    252   HiKeyUsbGetProduct,
    253   HiKeyUsbGetSerialNo,
    254   HiKeyUsbPhyInit
    255 };
    256 
    257 EFI_STATUS
    258 EFIAPI
    259 HiKeyUsbEntryPoint (
    260   IN EFI_HANDLE                            ImageHandle,
    261   IN EFI_SYSTEM_TABLE                      *SystemTable
    262   )
    263 {
    264   EFI_STATUS        Status;
    265 
    266   Status = gBS->InstallProtocolInterface (
    267                   &ImageHandle,
    268                   &gDwUsbProtocolGuid,
    269                   EFI_NATIVE_INTERFACE,
    270                   &mDwUsbDevice
    271                   );
    272   if (EFI_ERROR (Status)) {
    273     return Status;
    274   }
    275   return Status;
    276 }
    277