3 The SD host controller driver model and HC protocol routines.
5 Copyright (c) 2013-2016 Intel Corporation.
7 This program and the accompanying materials
8 are licensed and made available under the terms and conditions of the BSD License
9 which accompanies this distribution. The full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 #include "SDController.h"
22 EFI_DRIVER_BINDING_PROTOCOL gSDControllerDriverBinding
= {
23 SDControllerSupported
,
32 EFI_SD_HOST_IO_PROTOCOL mSDHostIo
= {
33 EFI_SD_HOST_IO_PROTOCOL_REVISION_01
,
35 0, // HighSpeedSupport
44 (512 * 1024) //BoundarySize
52 DetectCardAndInitHost
,
59 Find sdclk_freq_sel and upr_sdclk_freq_sel bits
60 for Clock Control Register (CLK_CTL)Offset 2Ch when using 8bit or 10bit
63 @param BaseClockFreg Base Clock Frequency in Hz For SD Clock in the
64 Capabilities register.
65 @param TargetFreq Target Frequency in Hz to reach.
66 @param Is8BitMode True if 8-bit Divided Clock Mode else 10bit mode.
67 @param Bits sdclk_freq_sel and upr_sdclk_freq_sel bits for
70 @return EFI_SUCCESS // Bits setup.
71 @return EFI_UNSUPPORTED // Cannot divide base clock to reach target clock.
74 DividedClockModeBits (
75 IN CONST UINTN BaseClockFreg
,
76 IN CONST UINTN TargetFreq
,
77 IN CONST BOOLEAN Is8BitMode
,
85 CurrFreq
= BaseClockFreg
;
88 // N == 0 same for 8bit & 10bit mode i.e. BaseClockFreg of controller.
90 if (TargetFreq
< CurrFreq
) {
95 // N values for 8bit mode when N > 0.
96 // Bit[15:8] SDCLK Frequency Select at offset 2Ch
97 // 80h - base clock divided by 256
98 // 40h - base clock divided by 128
99 // 20h - base clock divided by 64
100 // 10h - base clock divided by 32
101 // 08h - base clock divided by 16
102 // 04h - base clock divided by 8
103 // 02h - base clock divided by 4
104 // 01h - base clock divided by 2
106 CurrFreq
= BaseClockFreg
/ (2 * N
);
107 if (TargetFreq
>= CurrFreq
) {
111 if (N
> V_MMIO_CLKCTL_MAX_8BIT_FREQ_SEL
) {
112 return EFI_UNSUPPORTED
;
117 CurrFreq
= BaseClockFreg
/ (2 * N
);
119 // (try N = 0 or 1 first since don't want divide by 0).
121 if (TargetFreq
< CurrFreq
) {
123 // If still no match then calculate it for 10bit.
124 // N values for 10bit mode.
125 // N 1/2N Divided Clock (Duty 50%).
126 // from Spec "The length of divider is extended to 10 bits and all
127 // divider values shall be supported.
129 N
= (BaseClockFreg
/ TargetFreq
) / 2;
132 // Can only be N or N+1;
134 CurrFreq
= BaseClockFreg
/ (2 * N
);
135 if (TargetFreq
< CurrFreq
) {
137 CurrFreq
= BaseClockFreg
/ (2 * N
);
140 if (N
> V_MMIO_CLKCTL_MAX_10BIT_FREQ_SEL
) {
141 return EFI_UNSUPPORTED
;
145 // Set upper bits of SDCLK Frequency Select (bits 7:6 of reg 0x2c).
147 *Bits
|= ((UINT16
) ((N
>> 2) & B_MMIO_CLKCTL_UPR_SDCLK_FREQ_SEL_MASK
));
153 // Set lower bits of SDCLK Frequency Select (bits 15:8 of reg 0x2c).
155 *Bits
|= ((UINT16
) ((UINT8
) N
) << 8);
158 "SDIO:DividedClockModeBits: %dbit mode Want %dHz Got %dHz bits = %04x\r\n",
159 (Is8BitMode
) ? 8 : 10,
169 Print type of error and command index
171 @param CommandIndex Command index to set the command index field of command register.
172 @param ErrorCode Error interrupt status read from host controller
174 @return EFI_DEVICE_ERROR
176 @return EFI_CRC_ERROR
181 IN UINT16 CommandIndex
,
187 Status
= EFI_DEVICE_ERROR
;
189 DEBUG((EFI_D_ERROR
, "[%2d] -- ", CommandIndex
));
191 if (ErrorCode
& BIT0
) {
192 Status
= EFI_TIMEOUT
;
193 DEBUG((EFI_D_ERROR
, "Command Timeout Erro"));
196 if (ErrorCode
& BIT1
) {
197 Status
= EFI_CRC_ERROR
;
198 DEBUG((EFI_D_ERROR
, "Command CRC Error"));
201 if (ErrorCode
& BIT2
) {
202 DEBUG((EFI_D_ERROR
, "Command End Bit Error"));
205 if (ErrorCode
& BIT3
) {
206 DEBUG((EFI_D_ERROR
, "Command Index Error"));
208 if (ErrorCode
& BIT4
) {
209 Status
= EFI_TIMEOUT
;
210 DEBUG((EFI_D_ERROR
, "Data Timeout Error"));
213 if (ErrorCode
& BIT5
) {
214 Status
= EFI_CRC_ERROR
;
215 DEBUG((EFI_D_ERROR
, "Data CRC Error"));
218 if (ErrorCode
& BIT6
) {
219 DEBUG((EFI_D_ERROR
, "Data End Bit Error"));
222 if (ErrorCode
& BIT7
) {
223 DEBUG((EFI_D_ERROR
, "Current Limit Error"));
226 if (ErrorCode
& BIT8
) {
227 DEBUG((EFI_D_ERROR
, "Auto CMD12 Error"));
230 if (ErrorCode
& BIT9
) {
231 DEBUG((EFI_D_ERROR
, "ADMA Error"));
234 DEBUG((EFI_D_ERROR
, "\n"));
239 Enable/Disable High Speed transfer mode
241 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
242 @param Enable TRUE to Enable, FALSE to Disable
249 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
254 SDHOST_DATA
*SDHostData
;
255 EFI_PCI_IO_PROTOCOL
*PciIo
;
257 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
258 PciIo
= SDHostData
->PciIo
;
264 (UINT64
)MMIO_HOSTCTL
,
270 if (PcdGetBool(PcdSdHciQuirkNoHiSpd
)) {
271 DEBUG ((EFI_D_INFO
, "SDIO: Quirk never set High Speed Enable bit\r\n"));
274 DEBUG ((EFI_D_INFO
, "Enable High Speed transfer mode ... \r\n"));
283 (UINT64
)MMIO_HOSTCTL
,
292 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
297 SDHOST_DATA
*SDHostData
;
298 EFI_PCI_IO_PROTOCOL
*PciIo
;
299 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
300 PciIo
= SDHostData
->PciIo
;
305 (UINT64
)MMIO_HOSTCTL2
,
311 Data
|= 0x0004; // Enable DDR50 by default, later should enable other mode like HS200/400
312 Data
|= BIT3
; // Enable 1.8V Signaling
318 (UINT64
)MMIO_HOSTCTL2
,
325 Power on/off the LED associated with the slot
327 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
328 @param Enable TRUE to set LED on, FALSE to set LED off
334 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
338 SDHOST_DATA
*SDHostData
;
339 EFI_PCI_IO_PROTOCOL
*PciIo
;
342 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
343 PciIo
= SDHostData
->PciIo
;
349 (UINT64
)MMIO_HOSTCTL
,
370 (UINT64
)MMIO_HOSTCTL
,
380 The main function used to send the command to the card inserted into the SD host slot.
381 It will assemble the arguments to set the command register and wait for the command
382 and transfer completed until timeout. Then it will read the response register to fill
385 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
386 @param CommandIndex The command index to set the command index field of command register.
387 @param Argument Command argument to set the argument field of command register.
388 @param DataType TRANSFER_TYPE, indicates no data, data in or data out.
389 @param Buffer Contains the data read from / write to the device.
390 @param BufferSize The size of the buffer.
391 @param ResponseType RESPONSE_TYPE.
392 @param TimeOut Time out value in 1 ms unit.
393 @param ResponseData Depending on the ResponseType, such as CSD or card status.
396 @retval EFI_INVALID_PARAMETER
397 @retval EFI_OUT_OF_RESOURCES
399 @retval EFI_DEVICE_ERROR
406 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
407 IN UINT16 CommandIndex
,
409 IN TRANSFER_TYPE DataType
,
410 IN UINT8
*Buffer
, OPTIONAL
411 IN UINT32 BufferSize
,
412 IN RESPONSE_TYPE ResponseType
,
414 OUT UINT32
*ResponseData OPTIONAL
419 The main function used to send the command to the card inserted into the SD host
421 It will assemble the arguments to set the command register and wait for the command
422 and transfer completed until timeout. Then it will read the response register to fill
426 This - Pointer to EFI_SD_HOST_IO_PROTOCOL
427 CommandIndex - The command index to set the command index field of command register
428 Argument - Command argument to set the argument field of command register
429 DataType - TRANSFER_TYPE, indicates no data, data in or data out
430 Buffer - Contains the data read from / write to the device
431 BufferSize - The size of the buffer
432 ResponseType - RESPONSE_TYPE
433 TimeOut - Time out value in 1 ms unit
434 ResponseData - Depending on the ResponseType, such as CSD or card status
438 EFI_INVALID_PARAMETER
446 SDHOST_DATA
*SDHostData
;
447 EFI_PCI_IO_PROTOCOL
*PciIo
;
448 UINT32 ResponseDataCount
;
453 BOOLEAN AutoCMD12Enable
= FALSE
;
456 Status
= EFI_SUCCESS
;
457 ResponseDataCount
= 1;
458 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
459 PciIo
= SDHostData
->PciIo
;
460 AutoCMD12Enable
= (CommandIndex
& AUTO_CMD12_ENABLE
) ? TRUE
: FALSE
;
461 CommandIndex
= CommandIndex
& CMD_INDEX_MASK
;
463 if (Buffer
!= NULL
&& DataType
== NoData
) {
464 Status
= EFI_INVALID_PARAMETER
;
465 DEBUG ((EFI_D_ERROR
, "SendCommand: invalid parameter \r\n"));
469 if (((UINTN
)Buffer
& (This
->HostCapability
.BoundarySize
- 1)) != (UINTN
)NULL
) {
470 Status
= EFI_INVALID_PARAMETER
;
471 DEBUG ((EFI_D_ERROR
, "SendCommand: invalid parameter \r\n"));
475 DEBUG ((EFI_D_INFO
, "SendCommand: Command Index = %d \r\n", CommandIndex
));
477 TimeOut2
= 1000; // 10 ms
488 }while ((TimeOut2
-- > 0) && (Data
& BIT0
));
489 TimeOut2
= 1000; // 10 ms
500 }while ((TimeOut2
-- > 0) && (Data
& BIT1
));
508 (UINT64
)MMIO_NINTSTS
,
518 (UINT64
)MMIO_ERINTSTS
,
524 if (Buffer
!= NULL
) {
543 if (BufferSize
<= SDHostData
->BlockLength
) {
544 Data
|= (BufferSize
| 0x7000);
546 Data
|= (SDHostData
->BlockLength
| 0x7000);
558 if (BufferSize
<= SDHostData
->BlockLength
) {
561 Data
= BufferSize
/ SDHostData
->BlockLength
;
610 (UINT64
)MMIO_XFRMODE
,
616 DEBUG ((EFI_D_INFO
, "Transfer mode read = 0x%x \r\n", (Data
& 0xFFFF)));
621 if (DataType
== InData
) {
623 } else if (DataType
== OutData
){
627 Data
&= ~(BIT4
| BIT0
);
630 if (BufferSize
<= SDHostData
->BlockLength
) {
631 Data
&= ~ (BIT5
| BIT1
| BIT2
);
632 Data
|= BIT1
; // Enable block count always
634 if (SDHostData
->IsAutoStopCmd
&& AutoCMD12Enable
) {
635 Data
|= (BIT5
| BIT1
| BIT2
);
637 Data
|= (BIT5
| BIT1
);
641 DEBUG ((EFI_D_INFO
, "Transfer mode write = 0x%x \r\n", (Data
& 0xffff)));
646 (UINT64
)MMIO_XFRMODE
,
653 //ResponseTypeSelect IndexCheck CRCCheck ResponseType
657 // 10 1 1 R1, R5, R6, R7
660 switch (ResponseType
) {
662 Data
= (CommandIndex
<< 8);
663 ResponseDataCount
= 0;
670 Data
= (CommandIndex
<< 8) | BIT1
| BIT4
| BIT3
;
671 ResponseDataCount
= 1;
676 Data
= (CommandIndex
<< 8) | BIT0
| BIT1
| BIT4
| BIT3
;
677 ResponseDataCount
= 1;
681 Data
= (CommandIndex
<< 8) | BIT0
| BIT3
;
682 ResponseDataCount
= 4;
687 Data
= (CommandIndex
<< 8) | BIT1
;
688 ResponseDataCount
= 1;
693 Status
= EFI_INVALID_PARAMETER
;
694 DEBUG ((EFI_D_ERROR
, "SendCommand: invalid parameter \r\n"));
698 if (DataType
!= NoData
) {
702 HostLEDEnable (This
, TRUE
);
721 (UINT64
)MMIO_ERINTSTS
,
726 if ((Data
& 0x07FF) != 0) {
727 Status
= GetErrorReason (CommandIndex
, (UINT16
)Data
);
728 DEBUG ((EFI_D_ERROR
, "SendCommand: Error happens \r\n"));
736 (UINT64
)MMIO_NINTSTS
,
741 if ((Data
& BIT0
) == BIT0
) {
743 //Command completed, can read response
745 if (DataType
== NoData
) {
751 if ((Data
& BIT1
) == BIT1
) {
757 gBS
->Stall (1 * 1000);
761 } while (TimeOut
> 0);
764 Status
= EFI_TIMEOUT
;
765 DEBUG ((EFI_D_ERROR
, "SendCommand: Time out \r\n"));
769 if (ResponseData
!= NULL
) {
778 if (ResponseType
== ResponseR2
) {
780 // Adjustment for R2 response
783 for (Index
= 0; Index
< ResponseDataCount
; Index
++) {
784 Data64
= LShiftU64(*ResponseData
, 8);
785 *ResponseData
= (UINT32
)((Data64
& 0xFFFFFFFF) | Data
);
786 Data
= (UINT32
)RShiftU64 (Data64
, 32);
793 HostLEDEnable (This
, FALSE
);
798 Set max clock frequency of the host, the actual frequency may not be the same as MaxFrequency.
799 It depends on the max frequency the host can support, divider, and host speed mode.
801 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
802 @param MaxFrequency Max frequency in HZ.
811 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
812 IN UINT32 MaxFrequency
818 SDHOST_DATA
*SDHostData
;
819 EFI_PCI_IO_PROTOCOL
*PciIo
;
823 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
824 PciIo
= SDHostData
->PciIo
;
839 (UINT64
)MMIO_CTRLRVER
,
843 Revision
&= 0x000000FF;
845 Status
= DividedClockModeBits (
846 SDHostData
->BaseClockInMHz
* 1000 * 1000,
848 (Revision
< SDHCI_SPEC_300
),
852 if (EFI_ERROR (Status
)) {
854 // Cannot reach MaxFrequency with SDHostData->BaseClockInMHz.
856 ASSERT_EFI_ERROR (Status
);
863 //Enable internal clock and Stop Clock Enable
875 TimeOutCount
= TIME_OUT_1S
;
885 gBS
->Stall (1 * 1000);
887 if (TimeOutCount
== 0) {
888 DEBUG ((EFI_D_ERROR
, "SetClockFrequency: Time out \r\n"));
891 } while ((Data
& BIT1
) != BIT1
);
893 DEBUG ((EFI_D_INFO
, "Base Clock In MHz: %d\r\n", SDHostData
->BaseClockInMHz
));
895 Data
= (BIT0
| ((UINT32
) FreqSelBits
));
896 DEBUG ((EFI_D_INFO
, "Data write to MMIO_CLKCTL: 0x%04x \r\n", Data
));
906 TimeOutCount
= TIME_OUT_1S
;
916 gBS
->Stall (1 * 1000);
918 if (TimeOutCount
== 0) {
919 DEBUG ((EFI_D_ERROR
, "SetClockFrequency: Time out \r\n"));
922 } while ((Data
& BIT1
) != BIT1
);
923 gBS
->Stall (20 * 1000);
938 Set bus width of the host controller
940 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
941 @param BusWidth Bus width in 1, 4, 8 bits.
944 @retval EFI_INVALID_PARAMETER
950 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
954 SDHOST_DATA
*SDHostData
;
955 EFI_PCI_IO_PROTOCOL
*PciIo
;
958 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
961 if ((BusWidth
!= 1) && (BusWidth
!= 4) && (BusWidth
!= 8)) {
962 DEBUG ((EFI_D_ERROR
, "SetBusWidth: Invalid parameter \r\n"));
963 return EFI_INVALID_PARAMETER
;
966 if ((SDHostData
->SDHostIo
.HostCapability
.BusWidth8
== FALSE
) && (BusWidth
== 8)) {
967 DEBUG ((EFI_D_ERROR
, "SetBusWidth: Invalid parameter \r\n"));
968 return EFI_INVALID_PARAMETER
;
971 PciIo
= SDHostData
->PciIo
;
977 (UINT64
)MMIO_HOSTCTL
,
982 // BIT5 8-bit MMC Support (MMC8):
983 // If set, IOH supports 8-bit MMC. When cleared, IOH does not support this feature
986 DEBUG ((EFI_D_INFO
, "Bus Width is 8-bit ... \r\n"));
988 } else if (BusWidth
== 4) {
989 DEBUG ((EFI_D_INFO
, "Bus Width is 4-bit ... \r\n"));
993 DEBUG ((EFI_D_INFO
, "Bus Width is 1-bit ... \r\n"));
1002 (UINT64
)MMIO_HOSTCTL
,
1012 Set voltage which could supported by the host controller.
1013 Support 0(Power off the host), 1.8V, 3.0V, 3.3V
1015 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
1016 @param Voltage Units in 0.1 V.
1019 @retval EFI_INVALID_PARAMETER
1025 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
1029 SDHOST_DATA
*SDHostData
;
1030 EFI_PCI_IO_PROTOCOL
*PciIo
;
1034 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
1035 PciIo
= SDHostData
->PciIo
;
1036 Status
= EFI_SUCCESS
;
1042 (UINT64
)MMIO_PWRCTL
,
1049 //Power Off the host
1052 } else if (Voltage
<= 18 && This
->HostCapability
.V18Support
) {
1056 Data
|= (BIT1
| BIT3
| BIT0
);
1057 } else if (Voltage
> 18 && Voltage
<= 30 && This
->HostCapability
.V30Support
) {
1061 Data
|= (BIT2
| BIT3
| BIT0
);
1062 } else if (Voltage
> 30 && Voltage
<= 33 && This
->HostCapability
.V33Support
) {
1066 Data
|= (BIT1
| BIT2
| BIT3
| BIT0
);
1068 Status
= EFI_UNSUPPORTED
;
1076 (UINT64
)MMIO_PWRCTL
,
1080 gBS
->Stall (10 * 1000);
1089 Reset the host controller.
1091 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
1092 @param ResetAll TRUE to reset all.
1101 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
1102 IN RESET_TYPE ResetType
1105 SDHOST_DATA
*SDHostData
;
1106 EFI_PCI_IO_PROTOCOL
*PciIo
;
1110 UINT32 TimeOutCount
;
1114 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
1115 PciIo
= SDHostData
->PciIo
;
1119 if (ResetType
== Reset_Auto
) {
1122 EfiPciIoWidthUint16
,
1124 (UINT64
)MMIO_ERINTSTS
,
1128 if ((ErrStatus
& 0xF) != 0) {
1134 if ((ErrStatus
& 0x70) != 0) {
1143 if (ResetType
== Reset_DAT
|| ResetType
== Reset_DAT_CMD
) {
1146 if (ResetType
== Reset_CMD
|| ResetType
== Reset_DAT_CMD
) {
1149 if (ResetType
== Reset_All
) {
1158 // To improve SD stability, we zero the MMIO_CLKCTL register and
1159 // stall for 50 microseconds before reseting the controller. We
1160 // restore the register setting following the reset operation.
1164 EfiPciIoWidthUint16
,
1166 (UINT64
)MMIO_CLKCTL
,
1171 ZeroClkCtl
= (UINT16
) 0;
1174 EfiPciIoWidthUint16
,
1176 (UINT64
)MMIO_CLKCTL
,
1184 // Reset the SD host controller
1196 TimeOutCount
= TIME_OUT_1S
;
1199 gBS
->Stall (1 * 1000);
1211 if ((Data
& Mask
) == 0) {
1214 } while (TimeOutCount
> 0);
1217 // We now restore the MMIO_CLKCTL register which we set to 0 above.
1221 EfiPciIoWidthUint16
,
1223 (UINT64
)MMIO_CLKCTL
,
1228 if (TimeOutCount
== 0) {
1229 DEBUG ((EFI_D_ERROR
, "ResetSDHost: Time out \r\n"));
1238 Enable auto stop on the host controller.
1240 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
1241 @param Enable TRUE to enable, FALSE to disable.
1250 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
1254 SDHOST_DATA
*SDHostData
;
1256 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
1258 SDHostData
->IsAutoStopCmd
= Enable
;
1264 Set the Block length on the host controller.
1266 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
1267 @param BlockLength card supportes block length.
1276 IN EFI_SD_HOST_IO_PROTOCOL
*This
,
1277 IN UINT32 BlockLength
1280 SDHOST_DATA
*SDHostData
;
1282 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
1284 DEBUG ((EFI_D_INFO
, "Block length on the host controller: %d \r\n", BlockLength
));
1285 SDHostData
->BlockLength
= BlockLength
;
1292 Find whether these is a card inserted into the slot. If so init the host.
1293 If not, return EFI_NOT_FOUND.
1295 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
1298 @retval EFI_NOT_FOUND
1303 DetectCardAndInitHost (
1304 IN EFI_SD_HOST_IO_PROTOCOL
*This
1307 SDHOST_DATA
*SDHostData
;
1308 EFI_PCI_IO_PROTOCOL
*PciIo
;
1311 UINT8 Voltages
[] = { 33, 30, 18 };
1314 SDHostData
= SDHOST_DATA_FROM_THIS (This
);
1315 PciIo
= SDHostData
->PciIo
;
1316 Status
= EFI_NOT_FOUND
;
1321 EfiPciIoWidthUint32
,
1323 (UINT64
)MMIO_PSTATE
,
1328 if ((Data
& (BIT16
| BIT17
| BIT18
)) != (BIT16
| BIT17
| BIT18
)) {
1330 // Has no card inserted
1332 DEBUG ((EFI_D_INFO
, "DetectCardAndInitHost: No Cards \r\n"));
1333 Status
= EFI_NOT_FOUND
;
1336 DEBUG ((EFI_D_INFO
, "DetectCardAndInitHost: Find Cards \r\n"));
1338 Status
= EFI_NOT_FOUND
;
1339 for (Loop
= 0; Loop
< sizeof (Voltages
); Loop
++) {
1342 "DetectCardAndInitHost: SetHostVoltage %d.%dV \r\n",
1343 Voltages
[Loop
] / 10,
1346 Status
= SetHostVoltage (This
, Voltages
[Loop
]);
1347 if (EFI_ERROR (Status
)) {
1348 DEBUG ((EFI_D_INFO
, "DetectCardAndInitHost set voltages: [failed]\n"));
1350 DEBUG ((EFI_D_INFO
, "DetectCardAndInitHost set voltages: [success]\n"));
1354 if (EFI_ERROR (Status
)) {
1355 DEBUG ((EFI_D_ERROR
, "DetectCardAndInitHost: Fail to set voltage \r\n"));
1359 Status
= SetClockFrequency (This
, FREQUENCY_OD
);
1360 if (EFI_ERROR (Status
)) {
1361 DEBUG ((EFI_D_ERROR
, "DetectCardAndInitHost: Fail to set frequency \r\n"));
1364 SetBusWidth (This
, 1);
1367 //Enable normal status change
1370 Data
= (BIT0
| BIT1
);
1374 EfiPciIoWidthUint16
,
1376 (UINT64
)MMIO_NINTEN
,
1382 //Enable error status change
1386 EfiPciIoWidthUint16
,
1388 (UINT64
)MMIO_ERINTEN
,
1393 Data
|= (BIT0
| BIT1
| BIT2
| BIT3
| BIT4
| BIT5
| BIT6
| BIT7
| BIT8
);
1397 EfiPciIoWidthUint16
,
1399 (UINT64
)MMIO_ERINTEN
,
1405 //Data transfer Timeout control
1418 //Set Default Bus width as 1 bit
1427 Entry point for EFI drivers.
1429 @param ImageHandle EFI_HANDLE.
1430 @param SystemTable EFI_SYSTEM_TABLE.
1432 @retval EFI_SUCCESS Driver is successfully loaded.
1433 @return Others Failed.
1438 InitializeSDController (
1439 IN EFI_HANDLE ImageHandle
,
1440 IN EFI_SYSTEM_TABLE
*SystemTable
1443 return EfiLibInstallDriverBindingComponentName2 (
1446 &gSDControllerDriverBinding
,
1455 Test to see if this driver supports ControllerHandle. Any
1456 ControllerHandle that has SDHostIoProtocol installed will be supported.
1458 @param This Protocol instance pointer.
1459 @param Controller Handle of device to test.
1460 @param RemainingDevicePath Not used.
1462 @return EFI_SUCCESS This driver supports this device.
1463 @return EFI_UNSUPPORTED This driver does not support this device.
1468 SDControllerSupported (
1469 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1470 IN EFI_HANDLE Controller
,
1471 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1474 EFI_STATUS OpenStatus
;
1476 EFI_PCI_IO_PROTOCOL
*PciIo
;
1477 PCI_CLASSC PciClass
;
1478 EFI_SD_HOST_IO_PROTOCOL
*SdHostIo
;
1479 Status
= gBS
->OpenProtocol (
1481 &gEfiSDHostIoProtocolGuid
,
1483 This
->DriverBindingHandle
,
1485 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1487 if (!EFI_ERROR (Status
)) {
1488 DEBUG (( DEBUG_INFO
, "SdHost controller is already started\n"));
1489 return EFI_ALREADY_STARTED
;
1493 // Test whether there is PCI IO Protocol attached on the controller handle.
1495 OpenStatus
= gBS
->OpenProtocol (
1497 &gEfiPciIoProtocolGuid
,
1499 This
->DriverBindingHandle
,
1501 EFI_OPEN_PROTOCOL_BY_DRIVER
1504 if (EFI_ERROR (OpenStatus
)) {
1508 Status
= PciIo
->Pci
.Read (
1511 PCI_CLASSCODE_OFFSET
,
1512 sizeof (PCI_CLASSC
) / sizeof (UINT8
),
1516 if (EFI_ERROR (Status
)) {
1517 Status
= EFI_UNSUPPORTED
;
1522 // Test whether the controller belongs to SD type
1524 if ((PciClass
.BaseCode
!= PCI_CLASS_SYSTEM_PERIPHERAL
) ||
1525 (PciClass
.SubClassCode
!= PCI_SUBCLASS_SD_HOST_CONTROLLER
) ||
1526 ((PciClass
.PI
!= PCI_IF_STANDARD_HOST_NO_DMA
) && (PciClass
.PI
!= PCI_IF_STANDARD_HOST_SUPPORT_DMA
))
1529 Status
= EFI_UNSUPPORTED
;
1533 gBS
->CloseProtocol (
1535 &gEfiPciIoProtocolGuid
,
1536 This
->DriverBindingHandle
,
1543 Starting the SD Host Controller Driver.
1545 @param This Protocol instance pointer.
1546 @param Controller Handle of device to test.
1547 @param RemainingDevicePath Not used.
1549 @retval EFI_SUCCESS This driver supports this device.
1550 @retval EFI_UNSUPPORTED This driver does not support this device.
1551 @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.
1552 EFI_OUT_OF_RESOURCES- Failed due to resource shortage.
1558 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1559 IN EFI_HANDLE Controller
,
1560 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
1564 EFI_PCI_IO_PROTOCOL
*PciIo
;
1565 SDHOST_DATA
*SDHostData
;
1573 // Open PCI I/O Protocol and save pointer to open protocol
1574 // in private data area.
1576 Status
= gBS
->OpenProtocol (
1578 &gEfiPciIoProtocolGuid
,
1580 This
->DriverBindingHandle
,
1582 EFI_OPEN_PROTOCOL_BY_DRIVER
1585 if (EFI_ERROR (Status
)) {
1590 // Enable the SD Host Controller MMIO space
1592 Status
= PciIo
->Attributes (
1594 EfiPciIoAttributeOperationEnable
,
1595 EFI_PCI_DEVICE_ENABLE
,
1598 if (EFI_ERROR (Status
)) {
1599 Status
= EFI_OUT_OF_RESOURCES
;
1604 SDHostData
= (SDHOST_DATA
*)AllocateZeroPool(sizeof (SDHOST_DATA
));
1605 if (SDHostData
== NULL
) {
1606 Status
= EFI_OUT_OF_RESOURCES
;
1610 SDHostData
->Signature
= SDHOST_DATA_SIGNATURE
;
1611 SDHostData
->PciIo
= PciIo
;
1613 CopyMem (&SDHostData
->SDHostIo
, &mSDHostIo
, sizeof (EFI_SD_HOST_IO_PROTOCOL
));
1615 ResetSDHost (&SDHostData
->SDHostIo
, Reset_All
);
1619 EfiPciIoWidthUint16
,
1621 (UINT64
)MMIO_CTRLRVER
,
1625 SDHostData
->SDHostIo
.HostCapability
.HostVersion
= Data
& 0xFF;
1626 DEBUG ((EFI_D_INFO
, "SdHostDriverBindingStart: HostVersion 0x%x \r\n", SDHostData
->SDHostIo
.HostCapability
.HostVersion
));
1630 EfiPciIoWidthUint32
,
1636 DEBUG ((EFI_D_INFO
, "SdHostDriverBindingStart: MMIO_CAP 0x%x \r\n", Data
));
1637 if ((Data
& BIT18
) != 0) {
1638 SDHostData
->SDHostIo
.HostCapability
.BusWidth8
= TRUE
;
1641 if ((Data
& BIT21
) != 0) {
1642 SDHostData
->SDHostIo
.HostCapability
.HighSpeedSupport
= TRUE
;
1645 if ((Data
& BIT24
) != 0) {
1646 SDHostData
->SDHostIo
.HostCapability
.V33Support
= TRUE
;
1649 if ((Data
& BIT25
) != 0) {
1650 SDHostData
->SDHostIo
.HostCapability
.V30Support
= TRUE
;
1653 if ((Data
& BIT26
) != 0) {
1654 SDHostData
->SDHostIo
.HostCapability
.V18Support
= TRUE
;
1657 SDHostData
->SDHostIo
.HostCapability
.BusWidth4
= TRUE
;
1659 if(SDHostData
->SDHostIo
.HostCapability
.HostVersion
< SDHCI_SPEC_300
) {
1663 SDHostData
->BaseClockInMHz
= (Data
>> 8) & 0x3F;
1666 SDHostData
->BaseClockInMHz
= (Data
>> 8) & 0xFF;
1670 SDHostData
->BlockLength
= 512 << ((Data
>> 16) & 0x03);
1671 DEBUG ((EFI_D_INFO
, "SdHostDriverBindingStart: BlockLength 0x%x \r\n", SDHostData
->BlockLength
));
1672 SDHostData
->IsAutoStopCmd
= TRUE
;
1674 Status
= gBS
->InstallProtocolInterface (
1676 &gEfiSDHostIoProtocolGuid
,
1677 EFI_NATIVE_INTERFACE
,
1678 &SDHostData
->SDHostIo
1680 if (EFI_ERROR (Status
)) {
1685 // Install the component name protocol
1687 SDHostData
->ControllerNameTable
= NULL
;
1691 gSDControllerName
.SupportedLanguages
,
1692 &SDHostData
->ControllerNameTable
,
1693 L
"SD Host Controller",
1698 gSDControllerName2
.SupportedLanguages
,
1699 &SDHostData
->ControllerNameTable
,
1700 L
"SD Host Controller",
1705 if (EFI_ERROR (Status
)) {
1706 if (SDHostData
!= NULL
) {
1707 FreePool (SDHostData
);
1716 Stop this driver on ControllerHandle. Support stoping any child handles
1717 created by this driver.
1719 @param This Protocol instance pointer.
1720 @param Controller Handle of device to stop driver on.
1721 @param NumberOfChildren Number of Children in the ChildHandleBuffer.
1722 @param ChildHandleBuffer List of handles for the children we need to stop.
1731 IN EFI_DRIVER_BINDING_PROTOCOL
*This
,
1732 IN EFI_HANDLE Controller
,
1733 IN UINTN NumberOfChildren
,
1734 IN EFI_HANDLE
*ChildHandleBuffer
1738 EFI_SD_HOST_IO_PROTOCOL
*SDHostIo
;
1739 SDHOST_DATA
*SDHostData
;
1741 Status
= gBS
->OpenProtocol (
1743 &gEfiSDHostIoProtocolGuid
,
1744 (VOID
**) &SDHostIo
,
1745 This
->DriverBindingHandle
,
1747 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1751 // Test whether the Controller handler passed in is a valid
1752 // Usb controller handle that should be supported, if not,
1753 // return the error status directly
1755 if (EFI_ERROR (Status
)) {
1759 SetHostVoltage (SDHostIo
, 0);
1761 SDHostData
= SDHOST_DATA_FROM_THIS(SDHostIo
);
1764 // Uninstall Block I/O protocol from the device handle
1766 Status
= gBS
->UninstallProtocolInterface (
1768 &gEfiSDHostIoProtocolGuid
,
1771 if (EFI_ERROR (Status
)) {
1775 FreeUnicodeStringTable (SDHostData
->ControllerNameTable
);
1777 FreePool (SDHostData
);
1779 gBS
->CloseProtocol (
1781 &gEfiPciIoProtocolGuid
,
1782 This
->DriverBindingHandle
,