HiKeyDxe.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. /** @file
  2. *
  3. * Copyright (c) 2018, Linaro Ltd. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-2-Clause-Patent
  6. *
  7. **/
  8. #include <Library/CacheMaintenanceLib.h>
  9. #include <Library/DebugLib.h>
  10. #include <Library/DevicePathLib.h>
  11. #include <Library/IoLib.h>
  12. #include <Library/MemoryAllocationLib.h>
  13. #include <Library/PcdLib.h>
  14. #include <Library/UefiBootManagerLib.h>
  15. #include <Library/UefiBootServicesTableLib.h>
  16. #include <Library/UefiLib.h>
  17. #include <Protocol/DevicePath.h>
  18. #include <Protocol/DevicePathFromText.h>
  19. #include <Protocol/EmbeddedGpio.h>
  20. #include <Protocol/LoadedImage.h>
  21. #include <Protocol/PlatformBootManager.h>
  22. #include <Protocol/PlatformVirtualKeyboard.h>
  23. #include <Hi6220.h>
  24. #include <Hi6220RegsPeri.h>
  25. #include "HiKeyDxe.h"
  26. STATIC
  27. VOID
  28. UartInit (
  29. IN VOID
  30. )
  31. {
  32. UINT32 Val;
  33. /* make UART1 out of reset */
  34. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART1);
  35. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART1);
  36. /* make UART2 out of reset */
  37. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART2);
  38. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART2);
  39. /* make UART3 out of reset */
  40. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART3);
  41. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART3);
  42. /* make UART4 out of reset */
  43. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, PERIPH_RST3_UART4);
  44. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_CLKEN3, PERIPH_RST3_UART4);
  45. /* make DW_MMC2 out of reset */
  46. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS0, PERIPH_RST0_MMC2);
  47. /* enable clock for BT/WIFI */
  48. Val = MmioRead32 (PMUSSI_ONOFF8_REG) | PMUSSI_ONOFF8_EN_32KB;
  49. MmioWrite32 (PMUSSI_ONOFF8_REG, Val);
  50. }
  51. STATIC EMBEDDED_GPIO *mGpio;
  52. STATIC
  53. VOID
  54. MtcmosInit (
  55. IN VOID
  56. )
  57. {
  58. UINT32 Data;
  59. /* enable MTCMOS for GPU */
  60. MmioWrite32 (AO_CTRL_BASE + SC_PW_MTCMOS_EN0, PW_EN0_G3D);
  61. do {
  62. Data = MmioRead32 (AO_CTRL_BASE + SC_PW_MTCMOS_ACK_STAT0);
  63. } while ((Data & PW_EN0_G3D) == 0);
  64. }
  65. EFI_STATUS
  66. HiKeyInitPeripherals (
  67. IN VOID
  68. )
  69. {
  70. UINT32 Data, Bits;
  71. /* make I2C0/I2C1/I2C2/SPI0 out of reset */
  72. Bits = PERIPH_RST3_I2C0 | PERIPH_RST3_I2C1 | PERIPH_RST3_I2C2 | \
  73. PERIPH_RST3_SSP;
  74. MmioWrite32 (PERI_CTRL_BASE + SC_PERIPH_RSTDIS3, Bits);
  75. do {
  76. Data = MmioRead32 (PERI_CTRL_BASE + SC_PERIPH_RSTSTAT3);
  77. } while (Data & Bits);
  78. UartInit ();
  79. /* MTCMOS -- Multi-threshold CMOS */
  80. MtcmosInit ();
  81. /* Set DETECT_J15_FASTBOOT (GPIO24) pin as GPIO function */
  82. MmioWrite32 (IOCG_084_REG, 0); /* configure GPIO24 as nopull */
  83. MmioWrite32 (IOMG_080_REG, 0); /* configure GPIO24 as GPIO */
  84. return EFI_SUCCESS;
  85. }
  86. STATIC
  87. EFI_STATUS
  88. CreatePlatformBootOptionFromPath (
  89. IN CHAR16 *PathStr,
  90. IN CHAR16 *Description,
  91. IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
  92. )
  93. {
  94. EFI_STATUS Status;
  95. EFI_DEVICE_PATH *DevicePath;
  96. DevicePath = (EFI_DEVICE_PATH *)ConvertTextToDevicePath (PathStr);
  97. ASSERT (DevicePath != NULL);
  98. Status = EfiBootManagerInitializeLoadOption (
  99. BootOption,
  100. LoadOptionNumberUnassigned,
  101. LoadOptionTypeBoot,
  102. LOAD_OPTION_ACTIVE,
  103. Description,
  104. DevicePath,
  105. NULL,
  106. 0
  107. );
  108. FreePool (DevicePath);
  109. return Status;
  110. }
  111. STATIC
  112. EFI_STATUS
  113. CreatePlatformBootOptionFromGuid (
  114. IN EFI_GUID *FileGuid,
  115. IN CHAR16 *Description,
  116. IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
  117. )
  118. {
  119. EFI_STATUS Status;
  120. EFI_DEVICE_PATH *DevicePath;
  121. EFI_DEVICE_PATH *TempDevicePath;
  122. EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  123. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
  124. Status = gBS->HandleProtocol (
  125. gImageHandle,
  126. &gEfiLoadedImageProtocolGuid,
  127. (VOID **) &LoadedImage
  128. );
  129. ASSERT_EFI_ERROR (Status);
  130. EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
  131. TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
  132. ASSERT (TempDevicePath != NULL);
  133. DevicePath = AppendDevicePathNode (
  134. TempDevicePath,
  135. (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
  136. );
  137. ASSERT (DevicePath != NULL);
  138. Status = EfiBootManagerInitializeLoadOption (
  139. BootOption,
  140. LoadOptionNumberUnassigned,
  141. LoadOptionTypeBoot,
  142. LOAD_OPTION_ACTIVE,
  143. Description,
  144. DevicePath,
  145. NULL,
  146. 0
  147. );
  148. FreePool (DevicePath);
  149. return Status;
  150. }
  151. STATIC
  152. EFI_STATUS
  153. GetPlatformBootOptionsAndKeys (
  154. OUT UINTN *BootCount,
  155. OUT EFI_BOOT_MANAGER_LOAD_OPTION **BootOptions,
  156. OUT EFI_INPUT_KEY **BootKeys
  157. )
  158. {
  159. EFI_GUID *FileGuid;
  160. CHAR16 *PathStr;
  161. EFI_STATUS Status;
  162. UINTN Size;
  163. Size = sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * HIKEY_BOOT_OPTION_NUM;
  164. *BootOptions = (EFI_BOOT_MANAGER_LOAD_OPTION *)AllocateZeroPool (Size);
  165. if (*BootOptions == NULL) {
  166. DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootOptions\n"));
  167. return EFI_OUT_OF_RESOURCES;
  168. }
  169. Size = sizeof (EFI_INPUT_KEY) * HIKEY_BOOT_OPTION_NUM;
  170. *BootKeys = (EFI_INPUT_KEY *)AllocateZeroPool (Size);
  171. if (*BootKeys == NULL) {
  172. DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootKeys\n"));
  173. Status = EFI_OUT_OF_RESOURCES;
  174. goto Error;
  175. }
  176. PathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath);
  177. ASSERT (PathStr != NULL);
  178. Status = CreatePlatformBootOptionFromPath (
  179. PathStr,
  180. L"Boot from SD",
  181. &(*BootOptions)[0]
  182. );
  183. ASSERT_EFI_ERROR (Status);
  184. PathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
  185. ASSERT (PathStr != NULL);
  186. Status = CreatePlatformBootOptionFromPath (
  187. PathStr,
  188. L"Grub",
  189. &(*BootOptions)[1]
  190. );
  191. ASSERT_EFI_ERROR (Status);
  192. FileGuid = PcdGetPtr (PcdAndroidBootFile);
  193. ASSERT (FileGuid != NULL);
  194. Status = CreatePlatformBootOptionFromGuid (
  195. FileGuid,
  196. L"Android Boot",
  197. &(*BootOptions)[2]
  198. );
  199. ASSERT_EFI_ERROR (Status);
  200. FileGuid = PcdGetPtr (PcdAndroidFastbootFile);
  201. ASSERT (FileGuid != NULL);
  202. Status = CreatePlatformBootOptionFromGuid (
  203. FileGuid,
  204. L"Android Fastboot",
  205. &(*BootOptions)[3]
  206. );
  207. ASSERT_EFI_ERROR (Status);
  208. (*BootKeys)[3].ScanCode = SCAN_NULL;
  209. (*BootKeys)[3].UnicodeChar = 'f';
  210. *BootCount = 4;
  211. return EFI_SUCCESS;
  212. Error:
  213. FreePool (*BootOptions);
  214. return Status;
  215. }
  216. PLATFORM_BOOT_MANAGER_PROTOCOL mPlatformBootManager = {
  217. GetPlatformBootOptionsAndKeys
  218. };
  219. EFI_STATUS
  220. EFIAPI
  221. VirtualKeyboardRegister (
  222. IN VOID
  223. )
  224. {
  225. EFI_STATUS Status;
  226. Status = gBS->LocateProtocol (
  227. &gEmbeddedGpioProtocolGuid,
  228. NULL,
  229. (VOID **) &mGpio
  230. );
  231. if (EFI_ERROR (Status)) {
  232. return Status;
  233. }
  234. return EFI_SUCCESS;
  235. }
  236. EFI_STATUS
  237. EFIAPI
  238. VirtualKeyboardReset (
  239. IN VOID
  240. )
  241. {
  242. EFI_STATUS Status;
  243. if (mGpio == NULL) {
  244. return EFI_INVALID_PARAMETER;
  245. }
  246. Status = mGpio->Set (mGpio, DETECT_J15_FASTBOOT, GPIO_MODE_INPUT);
  247. return Status;
  248. }
  249. BOOLEAN
  250. EFIAPI
  251. VirtualKeyboardQuery (
  252. IN VIRTUAL_KBD_KEY *VirtualKey
  253. )
  254. {
  255. EFI_STATUS Status;
  256. UINTN Value = 0;
  257. if ((VirtualKey == NULL) || (mGpio == NULL)) {
  258. return FALSE;
  259. }
  260. if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
  261. goto Done;
  262. } else {
  263. Status = mGpio->Get (mGpio, DETECT_J15_FASTBOOT, &Value);
  264. if (EFI_ERROR (Status) || (Value != 0)) {
  265. return FALSE;
  266. }
  267. }
  268. Done:
  269. VirtualKey->Signature = VIRTUAL_KEYBOARD_KEY_SIGNATURE;
  270. VirtualKey->Key.ScanCode = SCAN_NULL;
  271. VirtualKey->Key.UnicodeChar = L'f';
  272. return TRUE;
  273. }
  274. EFI_STATUS
  275. EFIAPI
  276. VirtualKeyboardClear (
  277. IN VIRTUAL_KBD_KEY *VirtualKey
  278. )
  279. {
  280. if (VirtualKey == NULL) {
  281. return EFI_INVALID_PARAMETER;
  282. }
  283. if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
  284. MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_NONE);
  285. WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
  286. }
  287. return EFI_SUCCESS;
  288. }
  289. PLATFORM_VIRTUAL_KBD_PROTOCOL mVirtualKeyboard = {
  290. VirtualKeyboardRegister,
  291. VirtualKeyboardReset,
  292. VirtualKeyboardQuery,
  293. VirtualKeyboardClear
  294. };
  295. EFI_STATUS
  296. EFIAPI
  297. HiKeyEntryPoint (
  298. IN EFI_HANDLE ImageHandle,
  299. IN EFI_SYSTEM_TABLE *SystemTable
  300. )
  301. {
  302. EFI_STATUS Status;
  303. Status = HiKeyInitPeripherals ();
  304. if (EFI_ERROR (Status)) {
  305. return Status;
  306. }
  307. Status = gBS->InstallProtocolInterface (
  308. &ImageHandle,
  309. &gPlatformVirtualKeyboardProtocolGuid,
  310. EFI_NATIVE_INTERFACE,
  311. &mVirtualKeyboard
  312. );
  313. if (EFI_ERROR (Status)) {
  314. return Status;
  315. }
  316. Status = gBS->InstallProtocolInterface (
  317. &ImageHandle,
  318. &gPlatformBootManagerProtocolGuid,
  319. EFI_NATIVE_INTERFACE,
  320. &mPlatformBootManager
  321. );
  322. return Status;
  323. }