• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
HiKeyDetectUsbModeInit(IN 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
HiKeyGetUsbMode(IN VOID)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
HiKeyUsbPhyInit(IN UINT8 Mode)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
HiKeyUsbGetLang(OUT CHAR16 * Lang,OUT UINT8 * Length)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
HiKeyUsbGetManuFacturer(OUT CHAR16 * ManuFacturer,OUT UINT8 * Length)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
HiKeyUsbGetProduct(OUT CHAR16 * Product,OUT UINT8 * Length)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
HiKeyUsbGetSerialNo(OUT CHAR16 * SerialNo,OUT UINT8 * Length)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
HiKeyUsbEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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