1 /** @file
2 *
3 * Copyright (c) 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/BaseLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/DebugLib.h>
18 #include <Library/DevicePathLib.h>
19 #include <Library/IoLib.h>
20 #include <Library/TimerLib.h>
21 #include <Library/UefiBootServicesTableLib.h>
22 #include <Library/UefiLib.h>
23 #include <Library/UefiRuntimeServicesTableLib.h>
24 #include <Library/UsbSerialNumberLib.h>
25
26 #include <Protocol/EmbeddedGpio.h>
27 #include <Protocol/PlatformDwMmc.h>
28
29 #include <Hi3660.h>
30
31 #define DETECT_SD_CARD 203 // GPIO 25_3
32
33 DW_MMC_HC_SLOT_CAP
34 DwMmcCapability[1] = {
35 {
36 .HighSpeed = 1,
37 .BusWidth = 4,
38 .SlotType = RemovableSlot,
39 .CardType = SdCardType,
40 .Voltage30 = 1,
41 .BaseClkFreq = 3200
42 }
43 };
44
45 EFI_STATUS
46 EFIAPI
HiKey960GetCapability(IN EFI_HANDLE Controller,IN UINT8 Slot,OUT DW_MMC_HC_SLOT_CAP * Capability)47 HiKey960GetCapability (
48 IN EFI_HANDLE Controller,
49 IN UINT8 Slot,
50 OUT DW_MMC_HC_SLOT_CAP *Capability
51 )
52 {
53 if (Capability == NULL) {
54 return EFI_INVALID_PARAMETER;
55 }
56 if (DwMmcCapability[0].Controller == 0) {
57 DwMmcCapability[0].Controller = Controller;
58 CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
59 } else if (DwMmcCapability[0].Controller == Controller) {
60 CopyMem (Capability, &DwMmcCapability[0], sizeof (DW_MMC_HC_SLOT_CAP));
61 } else {
62 return EFI_INVALID_PARAMETER;
63 }
64 return EFI_SUCCESS;
65 }
66
67 BOOLEAN
68 EFIAPI
HiKey960CardDetect(IN EFI_HANDLE Controller,IN UINT8 Slot)69 HiKey960CardDetect (
70 IN EFI_HANDLE Controller,
71 IN UINT8 Slot
72 )
73 {
74 EFI_STATUS Status;
75 EMBEDDED_GPIO *Gpio;
76 UINTN Value;
77
78 if (Slot == 0) {
79 Status = gBS->LocateProtocol (&gEmbeddedGpioProtocolGuid, NULL, (VOID **)&Gpio);
80 if (EFI_ERROR (Status)) {
81 DEBUG ((DEBUG_ERROR, "Failed to get GPIO protocol: %r\n", Status));
82 goto Exit;
83 }
84 Status = Gpio->Set (Gpio, DETECT_SD_CARD, GPIO_MODE_INPUT);
85 if (EFI_ERROR (Status)) {
86 DEBUG ((DEBUG_ERROR, "Failed to sed GPIO as input mode: %r\n", Status));
87 goto Exit;
88 }
89 Status = Gpio->Get (Gpio, DETECT_SD_CARD, &Value);
90 if (EFI_ERROR (Status)) {
91 DEBUG ((DEBUG_ERROR, "Failed to get GPIO value: %r\n", Status));
92 goto Exit;
93 }
94 if (Value == 0) {
95 return TRUE;
96 }
97 }
98 Exit:
99 return FALSE;
100 }
101
102 PLATFORM_DW_MMC_PROTOCOL mDwMmcDevice = {
103 HiKey960GetCapability,
104 HiKey960CardDetect
105 };
106
107 EFI_STATUS
108 EFIAPI
HiKey960MmcEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)109 HiKey960MmcEntryPoint (
110 IN EFI_HANDLE ImageHandle,
111 IN EFI_SYSTEM_TABLE *SystemTable
112 )
113 {
114 EFI_STATUS Status;
115
116 Status = gBS->InstallProtocolInterface (
117 &ImageHandle,
118 &gPlatformDwMmcProtocolGuid,
119 EFI_NATIVE_INTERFACE,
120 &mDwMmcDevice
121 );
122 if (EFI_ERROR (Status)) {
123 return Status;
124 }
125 return Status;
126 }
127