123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461 |
- /** @file
- *
- * Copyright (c) 2018, Linaro Ltd. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-2-Clause-Patent
- *
- **/
- #include <Guid/EventGroup.h>
- #include <Hi3660.h>
- #include <Library/BaseLib.h>
- #include <Library/BaseMemoryLib.h>
- #include <Library/CacheMaintenanceLib.h>
- #include <Library/DebugLib.h>
- #include <Library/DevicePathLib.h>
- #include <Library/IoLib.h>
- #include <Library/MemoryAllocationLib.h>
- #include <Library/PrintLib.h>
- #include <Library/SerialPortLib.h>
- #include <Library/TimerLib.h>
- #include <Library/UefiBootManagerLib.h>
- #include <Library/UefiBootServicesTableLib.h>
- #include <Library/UefiLib.h>
- #include <Protocol/DevicePathFromText.h>
- #include <Protocol/EmbeddedGpio.h>
- #include <Protocol/LoadedImage.h>
- #include <Protocol/PlatformBootManager.h>
- #include <Protocol/PlatformVirtualKeyboard.h>
- #include "HiKey960Dxe.h"
- STATIC EMBEDDED_GPIO *mGpio;
- STATIC
- VOID
- InitSdCard (
- IN VOID
- )
- {
- UINT32 Data;
- //
- // LDO16
- // 000: 1.75V, 001: 1.8V, 010: 2.4V, 011: 2.6V, 100: 2.7V,
- // 101: 2.85V, 110: 2.95V, 111: 3.0V.
- //
- Data = MmioRead32 (PMIC_LDO16_VSET_REG) & LDO16_VSET_MASK;
- Data |= 6;
- MmioWrite32 (PMIC_LDO16_VSET_REG, Data);
- MmioOr32 (PMIC_LDO16_ONOFF_ECO_REG, LDO16_ONOFF_ECO_LDO16_ENABLE);
- //
- // wait regulator stable
- //
- MicroSecondDelay (100);
- //
- // LDO9
- // 000: 1.75V, 001: 1.8V, 010: 1.825V, 011: 2.8V, 100: 2.85V,
- // 101: 2.95V, 110: 3.0V, 111: 3.3V.
- //
- Data = MmioRead32 (PMIC_LDO9_VSET_REG) & LDO9_VSET_MASK;
- Data |= 5;
- MmioWrite32 (PMIC_LDO9_VSET_REG, Data);
- MmioOr32 (PMU_REG_BASE + (0x6a << 2), 2);
- //
- // wait regulator stable
- //
- MicroSecondDelay (100);
- //
- // GPIO203
- //
- MmioWrite32 (IOMG_AO_REG_BASE + (24 << 2), 0); // GPIO function
- //
- // SD pinmux
- //
- MmioWrite32 (IOMG_MMC0_000_REG, IOMG_FUNC1); // SD_CLK
- MmioWrite32 (IOMG_MMC0_001_REG, IOMG_FUNC1); // SD_CMD
- MmioWrite32 (IOMG_MMC0_002_REG, IOMG_FUNC1); // SD_DATA0
- MmioWrite32 (IOMG_MMC0_003_REG, IOMG_FUNC1); // SD_DATA1
- MmioWrite32 (IOMG_MMC0_004_REG, IOMG_FUNC1); // SD_DATA2
- MmioWrite32 (IOMG_MMC0_005_REG, IOMG_FUNC1); // SD_DATA3
- MmioWrite32 (IOCG_MMC0_000_REG, IOCG_DRIVE (15)); // SD_CLK float with 32mA
- MmioWrite32 (IOCG_MMC0_001_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_CMD
- MmioWrite32 (IOCG_MMC0_002_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA0
- MmioWrite32 (IOCG_MMC0_003_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA1
- MmioWrite32 (IOCG_MMC0_004_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA2
- MmioWrite32 (IOCG_MMC0_005_REG, IOCG_PULLUP | IOCG_DRIVE (8)); // SD_DATA3
- //
- // SC_SEL_SD:
- // 0xx: 3.2MHz, 100: PPLL0, 101: PPLL1, 11x: PPLL2.
- // SC_DIV_SD:
- // divider = value + 1
- //
- do {
- MmioOr32 (
- CRG_CLKDIV4,
- CLKDIV4_SC_SEL_SD (7) |
- (CLKDIV4_SC_SEL_SD_MASK << CLKDIV4_SC_MASK_SHIFT)
- );
- Data = MmioRead32 (CRG_CLKDIV4) & CLKDIV4_SC_SEL_SD_MASK;
- } while (Data != CLKDIV4_SC_SEL_SD (7));
- //
- // Unreset SD controller
- //
- MmioWrite32 (CRG_PERRSTDIS4, PERRSTEN4_SD);
- do {
- Data = MmioRead32 (CRG_PERRSTSTAT4);
- } while ((Data & PERRSTEN4_SD) == PERRSTEN4_SD);
- //
- // Enable SD controller clock
- //
- MmioOr32 (CRG_PEREN0, PEREN0_GT_HCLK_SD);
- MmioOr32 (CRG_PEREN4, PEREN4_GT_CLK_SD);
- do {
- Data = MmioRead32 (CRG_PERCLKEN4);
- } while ((Data & PEREN4_GT_CLK_SD) != PEREN4_GT_CLK_SD);
- }
- VOID
- InitPeripherals (
- IN VOID
- )
- {
- //
- // Enable FPLL0
- //
- MmioOr32 (SCTRL_SCFPLLCTRL0, SCTRL_SCFPLLCTRL0_FPLL0_EN);
- InitSdCard ();
- //
- // Enable wifi clock
- //
- MmioOr32 (PMIC_HARDWARE_CTRL0, PMIC_HARDWARE_CTRL0_WIFI_CLK);
- MmioOr32 (PMIC_OSC32K_ONOFF_CTRL, PMIC_OSC32K_ONOFF_CTRL_EN_32K);
- }
- /**
- Notification function of the event defined as belonging to the
- EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in
- the entry point of the driver.
- This function is called when an event belonging to the
- EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an
- event is signalled once at the end of the dispatching of all
- drivers (end of the so called DXE phase).
- @param[in] Event Event declared in the entry point of the driver whose
- notification function is being invoked.
- @param[in] Context NULL
- **/
- STATIC
- VOID
- OnEndOfDxe (
- IN EFI_EVENT Event,
- IN VOID *Context
- )
- {
- UINT32 BootMode;
- VOID *RecoveryStr;
- VOID *SwitchStr;
- BootMode = MmioRead32 (SCTRL_BAK_DATA0) & BOOT_MODE_MASK;
- if (BootMode == BOOT_MODE_RECOVERY) {
- RecoveryStr = "WARNING: CAN NOT BOOT KERNEL IN RECOVERY MODE!\r\n";
- SwitchStr = "Switch to normal boot mode, then reboot to boot kernel.\r\n";
- SerialPortWrite (RecoveryStr, AsciiStrLen (RecoveryStr));
- SerialPortWrite (SwitchStr, AsciiStrLen (SwitchStr));
- }
- }
- STATIC
- EFI_STATUS
- CreatePlatformBootOptionFromPath (
- IN CHAR16 *PathStr,
- IN CHAR16 *Description,
- IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
- )
- {
- EFI_STATUS Status;
- EFI_DEVICE_PATH *DevicePath;
- DevicePath = (EFI_DEVICE_PATH *)ConvertTextToDevicePath (PathStr);
- ASSERT (DevicePath != NULL);
- Status = EfiBootManagerInitializeLoadOption (
- BootOption,
- LoadOptionNumberUnassigned,
- LoadOptionTypeBoot,
- LOAD_OPTION_ACTIVE,
- Description,
- DevicePath,
- NULL,
- 0
- );
- FreePool (DevicePath);
- return Status;
- }
- STATIC
- EFI_STATUS
- CreatePlatformBootOptionFromGuid (
- IN EFI_GUID *FileGuid,
- IN CHAR16 *Description,
- IN OUT EFI_BOOT_MANAGER_LOAD_OPTION *BootOption
- )
- {
- EFI_STATUS Status;
- EFI_DEVICE_PATH *DevicePath;
- EFI_DEVICE_PATH *TempDevicePath;
- EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
- MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileNode;
- Status = gBS->HandleProtocol (
- gImageHandle,
- &gEfiLoadedImageProtocolGuid,
- (VOID **) &LoadedImage
- );
- ASSERT_EFI_ERROR (Status);
- EfiInitializeFwVolDevicepathNode (&FileNode, FileGuid);
- TempDevicePath = DevicePathFromHandle (LoadedImage->DeviceHandle);
- ASSERT (TempDevicePath != NULL);
- DevicePath = AppendDevicePathNode (
- TempDevicePath,
- (EFI_DEVICE_PATH_PROTOCOL *) &FileNode
- );
- ASSERT (DevicePath != NULL);
- Status = EfiBootManagerInitializeLoadOption (
- BootOption,
- LoadOptionNumberUnassigned,
- LoadOptionTypeBoot,
- LOAD_OPTION_ACTIVE,
- Description,
- DevicePath,
- NULL,
- 0
- );
- FreePool (DevicePath);
- return Status;
- }
- STATIC
- EFI_STATUS
- GetPlatformBootOptionsAndKeys (
- OUT UINTN *BootCount,
- OUT EFI_BOOT_MANAGER_LOAD_OPTION **BootOptions,
- OUT EFI_INPUT_KEY **BootKeys
- )
- {
- EFI_GUID *FileGuid;
- CHAR16 *PathStr;
- EFI_STATUS Status;
- UINTN Size;
- Size = sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * HIKEY960_BOOT_OPTION_NUM;
- *BootOptions = (EFI_BOOT_MANAGER_LOAD_OPTION *)AllocateZeroPool (Size);
- if (*BootOptions == NULL) {
- DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootOptions\n"));
- return EFI_OUT_OF_RESOURCES;
- }
- Size = sizeof (EFI_INPUT_KEY) * HIKEY960_BOOT_OPTION_NUM;
- *BootKeys = (EFI_INPUT_KEY *)AllocateZeroPool (Size);
- if (*BootKeys == NULL) {
- DEBUG ((DEBUG_ERROR, "Failed to allocate memory for BootKeys\n"));
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
- PathStr = (CHAR16 *)PcdGetPtr (PcdSdBootDevicePath);
- ASSERT (PathStr != NULL);
- Status = CreatePlatformBootOptionFromPath (
- PathStr,
- L"Boot from SD",
- &(*BootOptions)[0]
- );
- ASSERT_EFI_ERROR (Status);
- PathStr = (CHAR16 *)PcdGetPtr (PcdAndroidBootDevicePath);
- ASSERT (PathStr != NULL);
- Status = CreatePlatformBootOptionFromPath (
- PathStr,
- L"Grub",
- &(*BootOptions)[1]
- );
- ASSERT_EFI_ERROR (Status);
- FileGuid = PcdGetPtr (PcdAndroidBootFile);
- ASSERT (FileGuid != NULL);
- Status = CreatePlatformBootOptionFromGuid (
- FileGuid,
- L"Android Boot",
- &(*BootOptions)[2]
- );
- ASSERT_EFI_ERROR (Status);
- FileGuid = PcdGetPtr (PcdAndroidFastbootFile);
- ASSERT (FileGuid != NULL);
- Status = CreatePlatformBootOptionFromGuid (
- FileGuid,
- L"Android Fastboot",
- &(*BootOptions)[3]
- );
- ASSERT_EFI_ERROR (Status);
- (*BootKeys)[3].ScanCode = SCAN_NULL;
- (*BootKeys)[3].UnicodeChar = 'f';
- *BootCount = 4;
- return EFI_SUCCESS;
- Error:
- FreePool (*BootOptions);
- return Status;
- }
- PLATFORM_BOOT_MANAGER_PROTOCOL mPlatformBootManager = {
- GetPlatformBootOptionsAndKeys
- };
- EFI_STATUS
- EFIAPI
- VirtualKeyboardRegister (
- IN VOID
- )
- {
- EFI_STATUS Status;
- Status = gBS->LocateProtocol (
- &gEmbeddedGpioProtocolGuid,
- NULL,
- (VOID **) &mGpio
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- return EFI_SUCCESS;
- }
- EFI_STATUS
- EFIAPI
- VirtualKeyboardReset (
- IN VOID
- )
- {
- EFI_STATUS Status;
- if (mGpio == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Configure GPIO68 as GPIO function
- //
- MmioWrite32 (0xe896c108, 0);
- Status = mGpio->Set (mGpio, DETECT_SW_FASTBOOT, GPIO_MODE_INPUT);
- return Status;
- }
- BOOLEAN
- EFIAPI
- VirtualKeyboardQuery (
- IN VIRTUAL_KBD_KEY *VirtualKey
- )
- {
- EFI_STATUS Status;
- UINTN Value = 0;
- if ((VirtualKey == NULL) || (mGpio == NULL)) {
- return FALSE;
- }
- if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
- goto Done;
- } else {
- Status = mGpio->Get (mGpio, DETECT_SW_FASTBOOT, &Value);
- if (EFI_ERROR (Status) || (Value != 0)) {
- return FALSE;
- }
- }
- Done:
- VirtualKey->Signature = VIRTUAL_KEYBOARD_KEY_SIGNATURE;
- VirtualKey->Key.ScanCode = SCAN_NULL;
- VirtualKey->Key.UnicodeChar = L'f';
- return TRUE;
- }
- EFI_STATUS
- EFIAPI
- VirtualKeyboardClear (
- IN VIRTUAL_KBD_KEY *VirtualKey
- )
- {
- if (VirtualKey == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if (MmioRead32 (ADB_REBOOT_ADDRESS) == ADB_REBOOT_BOOTLOADER) {
- MmioWrite32 (ADB_REBOOT_ADDRESS, ADB_REBOOT_NONE);
- WriteBackInvalidateDataCacheRange ((VOID *)ADB_REBOOT_ADDRESS, 4);
- }
- return EFI_SUCCESS;
- }
- PLATFORM_VIRTUAL_KBD_PROTOCOL mVirtualKeyboard = {
- VirtualKeyboardRegister,
- VirtualKeyboardReset,
- VirtualKeyboardQuery,
- VirtualKeyboardClear
- };
- EFI_STATUS
- EFIAPI
- HiKey960EntryPoint (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_EVENT EndOfDxeEvent;
- InitPeripherals ();
- //
- // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.
- // The "OnEndOfDxe()" function is declared as the call back function.
- // It will be called at the end of the DXE phase when an event of the
- // same group is signalled to inform about the end of the DXE phase.
- // Install the INSTALL_FDT_PROTOCOL protocol.
- //
- Status = gBS->CreateEventEx (
- EVT_NOTIFY_SIGNAL,
- TPL_CALLBACK,
- OnEndOfDxe,
- NULL,
- &gEfiEndOfDxeEventGroupGuid,
- &EndOfDxeEvent
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gPlatformVirtualKeyboardProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mVirtualKeyboard
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- Status = gBS->InstallProtocolInterface (
- &ImageHandle,
- &gPlatformBootManagerProtocolGuid,
- EFI_NATIVE_INTERFACE,
- &mPlatformBootManager
- );
- return Status;
- }
|