HiKey960Dxe.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461
  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 <Guid/EventGroup.h>
  9. #include <Hi3660.h>
  10. #include <Library/BaseLib.h>
  11. #include <Library/BaseMemoryLib.h>
  12. #include <Library/CacheMaintenanceLib.h>
  13. #include <Library/DebugLib.h>
  14. #include <Library/DevicePathLib.h>
  15. #include <Library/IoLib.h>
  16. #include <Library/MemoryAllocationLib.h>
  17. #include <Library/PrintLib.h>
  18. #include <Library/SerialPortLib.h>
  19. #include <Library/TimerLib.h>
  20. #include <Library/UefiBootManagerLib.h>
  21. #include <Library/UefiBootServicesTableLib.h>
  22. #include <Library/UefiLib.h>
  23. #include <Protocol/DevicePathFromText.h>
  24. #include <Protocol/EmbeddedGpio.h>
  25. #include <Protocol/LoadedImage.h>
  26. #include <Protocol/PlatformBootManager.h>
  27. #include <Protocol/PlatformVirtualKeyboard.h>
  28. #include "HiKey960Dxe.h"
  29. STATIC EMBEDDED_GPIO *mGpio;
  30. STATIC
  31. VOID
  32. InitSdCard (
  33. IN VOID
  34. )
  35. {
  36. UINT32 Data;
  37. //
  38. // LDO16
  39. // 000: 1.75V, 001: 1.8V, 010: 2.4V, 011: 2.6V, 100: 2.7V,
  40. // 101: 2.85V, 110: 2.95V, 111: 3.0V.
  41. //
  42. Data = MmioRead32 (PMIC_LDO16_VSET_REG) & LDO16_VSET_MASK;
  43. Data |= 6;
  44. MmioWrite32 (PMIC_LDO16_VSET_REG, Data);
  45. MmioOr32 (PMIC_LDO16_ONOFF_ECO_REG, LDO16_ONOFF_ECO_LDO16_ENABLE);
  46. //
  47. // wait regulator stable
  48. //
  49. MicroSecondDelay (100);
  50. //
  51. // LDO9
  52. // 000: 1.75V, 001: 1.8V, 010: 1.825V, 011: 2.8V, 100: 2.85V,
  53. // 101: 2.95V, 110: 3.0V, 111: 3.3V.
  54. //
  55. Data = MmioRead32 (PMIC_LDO9_VSET_REG) & LDO9_VSET_MASK;
  56. Data |= 5;
  57. MmioWrite32 (PMIC_LDO9_VSET_REG, Data);
  58. MmioOr32 (PMU_REG_BASE + (0x6a << 2), 2);
  59. //
  60. // wait regulator stable
  61. //
  62. MicroSecondDelay (100);
  63. //
  64. // GPIO203
  65. //
  66. MmioWrite32 (IOMG_AO_REG_BASE + (24 << 2), 0); // GPIO function
  67. //
  68. // SD pinmux
  69. //
  70. MmioWrite32 (IOMG_MMC0_000_REG, IOMG_FUNC1); // SD_CLK
  71. MmioWrite32 (IOMG_MMC0_001_REG, IOMG_FUNC1); // SD_CMD
  72. MmioWrite32 (IOMG_MMC0_002_REG, IOMG_FUNC1); // SD_DATA0
  73. MmioWrite32 (IOMG_MMC0_003_REG, IOMG_FUNC1); // SD_DATA1
  74. MmioWrite32 (IOMG_MMC0_004_REG, IOMG_FUNC1); // SD_DATA2
  75. MmioWrite32 (IOMG_MMC0_005_REG, IOMG_FUNC1); // SD_DATA3
  76. MmioWrite32 (IOCG_MMC0_000_REG, IOCG_DRIVE (15)); // SD_CLK float with 32mA
  77. MmioWrite32 (IOCG_MMC0_001_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_CMD
  78. MmioWrite32 (IOCG_MMC0_002_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA0
  79. MmioWrite32 (IOCG_MMC0_003_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA1
  80. MmioWrite32 (IOCG_MMC0_004_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA2
  81. MmioWrite32 (IOCG_MMC0_005_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA3
  82. //
  83. // SC_SEL_SD:
  84. // 0xx: 3.2MHz, 100: PPLL0, 101: PPLL1, 11x: PPLL2.
  85. // SC_DIV_SD:
  86. // divider = value + 1
  87. //
  88. do {
  89. MmioOr32 (
  90. CRG_CLKDIV4,
  91. CLKDIV4_SC_SEL_SD (7) |
  92. (CLKDIV4_SC_SEL_SD_MASK << CLKDIV4_SC_MASK_SHIFT)
  93. );
  94. Data = MmioRead32 (CRG_CLKDIV4) & CLKDIV4_SC_SEL_SD_MASK;
  95. } while (Data != CLKDIV4_SC_SEL_SD (7));
  96. //
  97. // Unreset SD controller
  98. //
  99. MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_SD);
  100. do {
  101. Data = MmioRead32 (CRG_PERRSTSTAT4);
  102. } while ((Data & PERRSTEN4_SD) == PERRSTEN4_SD);
  103. //
  104. // Enable SD controller clock
  105. //
  106. MmioOr32 (CRG_PEREN0, PEREN0_GT_HCLK_SD);
  107. MmioOr32 (CRG_PEREN4, PEREN4_GT_CLK_SD);
  108. do {
  109. Data = MmioRead32 (CRG_PERCLKEN4);
  110. } while ((Data & PEREN4_GT_CLK_SD) != PEREN4_GT_CLK_SD);
  111. }
  112. VOID
  113. InitPeripherals (
  114. IN VOID
  115. )
  116. {
  117. //
  118. // Enable FPLL0
  119. //
  120. MmioOr32 (SCTRL_SCFPLLCTRL0, SCTRL_SCFPLLCTRL0_FPLL0_EN);
  121. InitSdCard ();
  122. //
  123. // Enable wifi clock
  124. //
  125. MmioOr32 (PMIC_HARDWARE_CTRL0, PMIC_HARDWARE_CTRL0_WIFI_CLK);
  126. MmioOr32 (PMIC_OSC32K_ONOFF_CTRL, PMIC_OSC32K_ONOFF_CTRL_EN_32K);
  127. }
  128. /**
  129. Notification function of the event defined as belonging to the
  130. EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
  131. the entry point of the driver.
  132. This function is called when an event belonging to the
  133. EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
  134. event is signalled once at the end of the dispatching of all
  135. drivers (end of the so called DXE phase).
  136. @param[in] Event Event declared in the entry point of the driver whose
  137. notification function is being invoked.
  138. @param[in] Context NULL
  139. **/
  140. STATIC
  141. VOID
  142. OnEndOfDxe (
  143. IN EFI_EVENT Event,
  144. IN VOID *Context
  145. )
  146. {
  147. UINT32 BootMode;
  148. VOID *RecoveryStr;
  149. VOID *SwitchStr;
  150. BootMode = MmioRead32 (SCTRL_BAK_DATA0) & BOOT_MODE_MASK;
  151. if (BootMode == BOOT_MODE_RECOVERY) {
  152. RecoveryStr = "WARNING: CAN NOT BOOT KERNEL IN RECOVERY MODE!\r\n";
  153. SwitchStr = "Switch to normal boot mode, then reboot to boot kernel.\r\n";
  154. SerialPortWrite (RecoveryStr, AsciiStrLen (RecoveryStr));
  155. SerialPortWrite (SwitchStr, AsciiStrLen (SwitchStr));
  156. }
  157. }
  158. STATIC
  159. EFI_STATUS
  160. CreatePlatformBootOptionFromPath (
  161. IN CHAR16 *PathStr,
  162. IN CHAR16 *Description,
  163. IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
  164. )
  165. {
  166. EFI_STATUS Status;
  167. EFI_DEVICE_PATH *DevicePath;
  168. DevicePath = (EFI_DEVICE_PATH *)ConvertTextToDevicePath (PathStr);
  169. ASSERT (DevicePath != NULL);
  170. Status = EfiBootManagerInitializeLoadOption (
  171. BootOption,
  172. LoadOptionNumberUnassigned,
  173. LoadOptionTypeBoot,
  174. LOAD_OPTION_ACTIVE,
  175. Description,
  176. DevicePath,
  177. NULL,
  178. 0
  179. );
  180. FreePool (DevicePath);
  181. return Status;
  182. }
  183. STATIC
  184. EFI_STATUS
  185. CreatePlatformBootOptionFromGuid (
  186. IN EFI_GUID *FileGuid,
  187. IN CHAR16 *Description,
  188. IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
  189. )
  190. {
  191. EFI_STATUS Status;
  192. EFI_DEVICE_PATH *DevicePath;
  193. EFI_DEVICE_PATH *TempDevicePath;
  194. EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
  195. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
  196. Status = gBS->HandleProtocol (
  197. gImageHandle,
  198. &gEfiLoadedImageProtocolGuid,
  199. (VOID **) &LoadedImage
  200. );
  201. ASSERT_EFI_ERROR (Status);
  202. EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
  203. TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
  204. ASSERT (TempDevicePath != NULL);
  205. DevicePath = AppendDevicePathNode (
  206. TempDevicePath,
  207. (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
  208. );
  209. ASSERT (DevicePath != NULL);
  210. Status = EfiBootManagerInitializeLoadOption (
  211. BootOption,
  212. LoadOptionNumberUnassigned,
  213. LoadOptionTypeBoot,
  214. LOAD_OPTION_ACTIVE,
  215. Description,
  216. DevicePath,
  217. NULL,
  218. 0
  219. );
  220. FreePool (DevicePath);
  221. return Status;
  222. }
  223. STATIC
  224. EFI_STATUS
  225. GetPlatformBootOptionsAndKeys (
  226. OUT UINTN *BootCount,
  227. OUT EFI_BOOT_MANAGER_LOAD_OPTION **BootOptions,
  228. OUT EFI_INPUT_KEY **BootKeys
  229. )
  230. {
  231. EFI_GUID *FileGuid;
  232. CHAR16 *PathStr;
  233. EFI_STATUS Status;
  234. UINTN Size;
  235. Size = sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * HIKEY960_BOOT_OPTION_NUM;
  236. *BootOptions = (EFI_BOOT_MANAGER_LOAD_OPTION *)AllocateZeroPool (Size);
  237. if (*BootOptions == NULL) {
  238. DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootOptions\n"));
  239. return EFI_OUT_OF_RESOURCES;
  240. }
  241. Size = sizeof (EFI_INPUT_KEY) * HIKEY960_BOOT_OPTION_NUM;
  242. *BootKeys = (EFI_INPUT_KEY *)AllocateZeroPool (Size);
  243. if (*BootKeys == NULL) {
  244. DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootKeys\n"));
  245. Status = EFI_OUT_OF_RESOURCES;
  246. goto Error;
  247. }
  248. PathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath);
  249. ASSERT (PathStr != NULL);
  250. Status = CreatePlatformBootOptionFromPath (
  251. PathStr,
  252. L"Boot from SD",
  253. &(*BootOptions)[0]
  254. );
  255. ASSERT_EFI_ERROR (Status);
  256. PathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
  257. ASSERT (PathStr != NULL);
  258. Status = CreatePlatformBootOptionFromPath (
  259. PathStr,
  260. L"Grub",
  261. &(*BootOptions)[1]
  262. );
  263. ASSERT_EFI_ERROR (Status);
  264. FileGuid = PcdGetPtr (PcdAndroidBootFile);
  265. ASSERT (FileGuid != NULL);
  266. Status = CreatePlatformBootOptionFromGuid (
  267. FileGuid,
  268. L"Android Boot",
  269. &(*BootOptions)[2]
  270. );
  271. ASSERT_EFI_ERROR (Status);
  272. FileGuid = PcdGetPtr (PcdAndroidFastbootFile);
  273. ASSERT (FileGuid != NULL);
  274. Status = CreatePlatformBootOptionFromGuid (
  275. FileGuid,
  276. L"Android Fastboot",
  277. &(*BootOptions)[3]
  278. );
  279. ASSERT_EFI_ERROR (Status);
  280. (*BootKeys)[3].ScanCode = SCAN_NULL;
  281. (*BootKeys)[3].UnicodeChar = 'f';
  282. *BootCount = 4;
  283. return EFI_SUCCESS;
  284. Error:
  285. FreePool (*BootOptions);
  286. return Status;
  287. }
  288. PLATFORM_BOOT_MANAGER_PROTOCOL mPlatformBootManager = {
  289. GetPlatformBootOptionsAndKeys
  290. };
  291. EFI_STATUS
  292. EFIAPI
  293. VirtualKeyboardRegister (
  294. IN VOID
  295. )
  296. {
  297. EFI_STATUS Status;
  298. Status = gBS->LocateProtocol (
  299. &gEmbeddedGpioProtocolGuid,
  300. NULL,
  301. (VOID **) &mGpio
  302. );
  303. if (EFI_ERROR (Status)) {
  304. return Status;
  305. }
  306. return EFI_SUCCESS;
  307. }
  308. EFI_STATUS
  309. EFIAPI
  310. VirtualKeyboardReset (
  311. IN VOID
  312. )
  313. {
  314. EFI_STATUS Status;
  315. if (mGpio == NULL) {
  316. return EFI_INVALID_PARAMETER;
  317. }
  318. //
  319. // Configure GPIO68 as GPIO function
  320. //
  321. MmioWrite32 (0xe896c108, 0);
  322. Status = mGpio->Set (mGpio, DETECT_SW_FASTBOOT, GPIO_MODE_INPUT);
  323. return Status;
  324. }
  325. BOOLEAN
  326. EFIAPI
  327. VirtualKeyboardQuery (
  328. IN VIRTUAL_KBD_KEY *VirtualKey
  329. )
  330. {
  331. EFI_STATUS Status;
  332. UINTN Value = 0;
  333. if ((VirtualKey == NULL) || (mGpio == NULL)) {
  334. return FALSE;
  335. }
  336. if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
  337. goto Done;
  338. } else {
  339. Status = mGpio->Get (mGpio, DETECT_SW_FASTBOOT, &Value);
  340. if (EFI_ERROR (Status) || (Value != 0)) {
  341. return FALSE;
  342. }
  343. }
  344. Done:
  345. VirtualKey->Signature = VIRTUAL_KEYBOARD_KEY_SIGNATURE;
  346. VirtualKey->Key.ScanCode = SCAN_NULL;
  347. VirtualKey->Key.UnicodeChar = L'f';
  348. return TRUE;
  349. }
  350. EFI_STATUS
  351. EFIAPI
  352. VirtualKeyboardClear (
  353. IN VIRTUAL_KBD_KEY *VirtualKey
  354. )
  355. {
  356. if (VirtualKey == NULL) {
  357. return EFI_INVALID_PARAMETER;
  358. }
  359. if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
  360. MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_NONE);
  361. WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
  362. }
  363. return EFI_SUCCESS;
  364. }
  365. PLATFORM_VIRTUAL_KBD_PROTOCOL mVirtualKeyboard = {
  366. VirtualKeyboardRegister,
  367. VirtualKeyboardReset,
  368. VirtualKeyboardQuery,
  369. VirtualKeyboardClear
  370. };
  371. EFI_STATUS
  372. EFIAPI
  373. HiKey960EntryPoint (
  374. IN EFI_HANDLE ImageHandle,
  375. IN EFI_SYSTEM_TABLE *SystemTable
  376. )
  377. {
  378. EFI_STATUS Status;
  379. EFI_EVENT EndOfDxeEvent;
  380. InitPeripherals ();
  381. //
  382. // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
  383. // The "OnEndOfDxe()" function is declared as the call back function.
  384. // It will be called at the end of the DXE phase when an event of the
  385. // same group is signalled to inform about the end of the DXE phase.
  386. // Install the INSTALL_FDT_PROTOCOL protocol.
  387. //
  388. Status = gBS->CreateEventEx (
  389. EVT_NOTIFY_SIGNAL,
  390. TPL_CALLBACK,
  391. OnEndOfDxe,
  392. NULL,
  393. &gEfiEndOfDxeEventGroupGuid,
  394. &EndOfDxeEvent
  395. );
  396. if (EFI_ERROR (Status)) {
  397. return Status;
  398. }
  399. Status = gBS->InstallProtocolInterface (
  400. &ImageHandle,
  401. &gPlatformVirtualKeyboardProtocolGuid,
  402. EFI_NATIVE_INTERFACE,
  403. &mVirtualKeyboard
  404. );
  405. if (EFI_ERROR (Status)) {
  406. return Status;
  407. }
  408. Status = gBS->InstallProtocolInterface (
  409. &ImageHandle,
  410. &gPlatformBootManagerProtocolGuid,
  411. EFI_NATIVE_INTERFACE,
  412. &mPlatformBootManager
  413. );
  414. return Status;
  415. }