]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/SdMmcPciHcDxe: Allow additional SDHCI versions
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdDevice.c
1 /** @file
2 This file provides some helper functions which are specific for SD card device.
3
4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
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 "SdMmcPciHcDxe.h"
16
17 /**
18 Send command GO_IDLE_STATE to the device to make it go to Idle State.
19
20 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
21
22 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
23 @param[in] Slot The slot number of the SD card to send the command to.
24
25 @retval EFI_SUCCESS The SD device is reset correctly.
26 @retval Others The device reset fails.
27
28 **/
29 EFI_STATUS
30 SdCardReset (
31 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
32 IN UINT8 Slot
33 )
34 {
35 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
36 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
37 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
38 EFI_STATUS Status;
39
40 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
41 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
42 ZeroMem (&Packet, sizeof (Packet));
43
44 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
45 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
46 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
47
48 SdMmcCmdBlk.CommandIndex = SD_GO_IDLE_STATE;
49 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBc;
50
51 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
52
53 return Status;
54 }
55
56 /**
57 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
58 condition.
59
60 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
61
62 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
63 @param[in] Slot The slot number of the SD card to send the command to.
64 @param[in] SupplyVoltage The supplied voltage by the host.
65 @param[in] CheckPattern The check pattern to be sent to the device.
66
67 @retval EFI_SUCCESS The operation is done correctly.
68 @retval Others The operation fails.
69
70 **/
71 EFI_STATUS
72 SdCardVoltageCheck (
73 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
74 IN UINT8 Slot,
75 IN UINT8 SupplyVoltage,
76 IN UINT8 CheckPattern
77 )
78 {
79 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
80 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
81 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
82 EFI_STATUS Status;
83
84 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
85 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
86 ZeroMem (&Packet, sizeof (Packet));
87
88 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
89 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
90 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
91
92 SdMmcCmdBlk.CommandIndex = SD_SEND_IF_COND;
93 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
94 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR7;
95 SdMmcCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern;
96
97 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
98
99 if (!EFI_ERROR (Status)) {
100 if (SdMmcStatusBlk.Resp0 != SdMmcCmdBlk.CommandArgument) {
101 return EFI_DEVICE_ERROR;
102 }
103 }
104
105 return Status;
106 }
107
108 /**
109 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
110
111 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
112
113 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
114 @param[in] Slot The slot number of the SD card to send the command to.
115 @param[in] VoltageWindow The supply voltage window.
116 @param[in] S18R The boolean to show if it should switch to 1.8v.
117
118 @retval EFI_SUCCESS The operation is done correctly.
119 @retval Others The operation fails.
120
121 **/
122 EFI_STATUS
123 SdioSendOpCond (
124 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
125 IN UINT8 Slot,
126 IN UINT32 VoltageWindow,
127 IN BOOLEAN S18R
128 )
129 {
130 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
131 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
132 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
133 EFI_STATUS Status;
134 UINT32 Switch;
135
136 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
137 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
138 ZeroMem (&Packet, sizeof (Packet));
139
140 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
141 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
142 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
143
144 SdMmcCmdBlk.CommandIndex = SDIO_SEND_OP_COND;
145 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
146 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR4;
147
148 Switch = S18R ? BIT24 : 0;
149
150 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch;
151
152 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
153
154 return Status;
155 }
156
157 /**
158 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
159
160 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
161
162 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
163 @param[in] Slot The slot number of the SD card to send the command to.
164 @param[in] Rca The relative device address of addressed device.
165 @param[in] VoltageWindow The supply voltage window.
166 @param[in] S18R The boolean to show if it should switch to 1.8v.
167 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
168 @param[in] Hcs The boolean to show if it support host capacity info.
169 @param[out] Ocr The buffer to store returned OCR register value.
170
171 @retval EFI_SUCCESS The operation is done correctly.
172 @retval Others The operation fails.
173
174 **/
175 EFI_STATUS
176 SdCardSendOpCond (
177 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
178 IN UINT8 Slot,
179 IN UINT16 Rca,
180 IN UINT32 VoltageWindow,
181 IN BOOLEAN S18R,
182 IN BOOLEAN Xpc,
183 IN BOOLEAN Hcs,
184 OUT UINT32 *Ocr
185 )
186 {
187 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
188 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
189 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
190 EFI_STATUS Status;
191 UINT32 Switch;
192 UINT32 MaxPower;
193 UINT32 HostCapacity;
194
195 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
196 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
197 ZeroMem (&Packet, sizeof (Packet));
198
199 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
200 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
201 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
202
203 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
204 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
205 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
206 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
207
208 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
209 if (EFI_ERROR (Status)) {
210 return Status;
211 }
212
213 SdMmcCmdBlk.CommandIndex = SD_SEND_OP_COND;
214 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
215 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3;
216
217 Switch = S18R ? BIT24 : 0;
218 MaxPower = Xpc ? BIT28 : 0;
219 HostCapacity = Hcs ? BIT30 : 0;
220
221 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity;
222
223 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
224 if (!EFI_ERROR (Status)) {
225 //
226 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
227 //
228 *Ocr = SdMmcStatusBlk.Resp0;
229 }
230
231 return Status;
232 }
233
234 /**
235 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
236 data of their CID registers.
237
238 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
239
240 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
241 @param[in] Slot The slot number of the SD card to send the command to.
242
243 @retval EFI_SUCCESS The operation is done correctly.
244 @retval Others The operation fails.
245
246 **/
247 EFI_STATUS
248 SdCardAllSendCid (
249 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
250 IN UINT8 Slot
251 )
252 {
253 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
254 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
255 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
256 EFI_STATUS Status;
257
258 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
259 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
260 ZeroMem (&Packet, sizeof (Packet));
261
262 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
263 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
264 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
265
266 SdMmcCmdBlk.CommandIndex = SD_ALL_SEND_CID;
267 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
268 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
269
270 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
271
272 return Status;
273 }
274
275 /**
276 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
277 Address (RCA).
278
279 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
280
281 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
282 @param[in] Slot The slot number of the SD card to send the command to.
283 @param[out] Rca The relative device address to assign.
284
285 @retval EFI_SUCCESS The operation is done correctly.
286 @retval Others The operation fails.
287
288 **/
289 EFI_STATUS
290 SdCardSetRca (
291 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
292 IN UINT8 Slot,
293 OUT UINT16 *Rca
294 )
295 {
296 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
297 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
298 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
299 EFI_STATUS Status;
300
301 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
302 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
303 ZeroMem (&Packet, sizeof (Packet));
304
305 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
306 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
307 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
308
309 SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR;
310 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
311 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6;
312
313 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
314 if (!EFI_ERROR (Status)) {
315 *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16);
316 }
317
318 return Status;
319 }
320
321
322
323
324
325 /**
326 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
327
328 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
329
330 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
331 @param[in] Slot The slot number of the SD card to send the command to.
332 @param[in] Rca The relative device address of selected device.
333
334 @retval EFI_SUCCESS The operation is done correctly.
335 @retval Others The operation fails.
336
337 **/
338 EFI_STATUS
339 SdCardSelect (
340 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
341 IN UINT8 Slot,
342 IN UINT16 Rca
343 )
344 {
345 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
346 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
347 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
348 EFI_STATUS Status;
349
350 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
351 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
352 ZeroMem (&Packet, sizeof (Packet));
353
354 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
355 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
356 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
357
358 SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD;
359 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
360 if (Rca != 0) {
361 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
362 }
363 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
364
365 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
366
367 return Status;
368 }
369
370 /**
371 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
372
373 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
374
375 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
376 @param[in] Slot The slot number of the SD card to send the command to.
377
378 @retval EFI_SUCCESS The operation is done correctly.
379 @retval Others The operation fails.
380
381 **/
382 EFI_STATUS
383 SdCardVoltageSwitch (
384 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
385 IN UINT8 Slot
386 )
387 {
388 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
389 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
390 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
391 EFI_STATUS Status;
392
393 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
394 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
395 ZeroMem (&Packet, sizeof (Packet));
396
397 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
398 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
399 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
400
401 SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;
402 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
403 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
404 SdMmcCmdBlk.CommandArgument = 0;
405
406 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
407
408 return Status;
409 }
410
411 /**
412 Send command SET_BUS_WIDTH to the SD device to set the bus width.
413
414 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
415
416 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
417 @param[in] Slot The slot number of the SD card to send the command to.
418 @param[in] Rca The relative device address of addressed device.
419 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
420
421 @retval EFI_SUCCESS The operation is done correctly.
422 @retval Others The operation fails.
423
424 **/
425 EFI_STATUS
426 SdCardSetBusWidth (
427 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
428 IN UINT8 Slot,
429 IN UINT16 Rca,
430 IN UINT8 BusWidth
431 )
432 {
433 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
434 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
435 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
436 EFI_STATUS Status;
437 UINT8 Value;
438
439 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
440 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
441 ZeroMem (&Packet, sizeof (Packet));
442
443 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
444 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
445 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
446
447 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
448 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
449 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
450 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
451
452 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
453 if (EFI_ERROR (Status)) {
454 return Status;
455 }
456
457 SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;
458 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
459 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
460
461 if (BusWidth == 1) {
462 Value = 0;
463 } else if (BusWidth == 4) {
464 Value = 2;
465 } else {
466 return EFI_INVALID_PARAMETER;
467 }
468
469 SdMmcCmdBlk.CommandArgument = Value & 0x3;
470
471 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
472 return Status;
473 }
474
475 /**
476 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
477
478 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
479
480 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
481 @param[in] Slot The slot number of the SD card to send the command to.
482 @param[in] AccessMode The value for access mode group.
483 @param[in] CommandSystem The value for command set group.
484 @param[in] DriveStrength The value for drive length group.
485 @param[in] PowerLimit The value for power limit group.
486 @param[in] Mode Switch or check function.
487 @param[out] SwitchResp The return switch function status.
488
489 @retval EFI_SUCCESS The operation is done correctly.
490 @retval Others The operation fails.
491
492 **/
493 EFI_STATUS
494 SdCardSwitch (
495 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
496 IN UINT8 Slot,
497 IN UINT8 AccessMode,
498 IN UINT8 CommandSystem,
499 IN UINT8 DriveStrength,
500 IN UINT8 PowerLimit,
501 IN BOOLEAN Mode,
502 OUT UINT8 *SwitchResp
503 )
504 {
505 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
506 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
507 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
508 EFI_STATUS Status;
509 UINT32 ModeValue;
510
511 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
512 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
513 ZeroMem (&Packet, sizeof (Packet));
514
515 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
516 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
517 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
518
519 SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;
520 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
521 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
522
523 ModeValue = Mode ? BIT31 : 0;
524 SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \
525 ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \
526 ModeValue;
527
528 Packet.InDataBuffer = SwitchResp;
529 Packet.InTransferLength = 64;
530
531 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
532
533 return Status;
534 }
535
536 /**
537 Send command SEND_STATUS to the addressed SD device to get its status register.
538
539 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
540
541 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
542 @param[in] Slot The slot number of the SD card to send the command to.
543 @param[in] Rca The relative device address of addressed device.
544 @param[out] DevStatus The returned device status.
545
546 @retval EFI_SUCCESS The operation is done correctly.
547 @retval Others The operation fails.
548
549 **/
550 EFI_STATUS
551 SdCardSendStatus (
552 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
553 IN UINT8 Slot,
554 IN UINT16 Rca,
555 OUT UINT32 *DevStatus
556 )
557 {
558 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
559 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
560 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
561 EFI_STATUS Status;
562
563 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
564 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
565 ZeroMem (&Packet, sizeof (Packet));
566
567 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
568 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
569 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
570
571 SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;
572 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
573 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
574 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
575
576 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
577 if (!EFI_ERROR (Status)) {
578 *DevStatus = SdMmcStatusBlk.Resp0;
579 }
580
581 return Status;
582 }
583
584 /**
585 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
586 detection.
587
588 It may be sent up to 40 times until the host finishes the tuning procedure.
589
590 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
591
592 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
593 @param[in] Slot The slot number of the SD card to send the command to.
594
595 @retval EFI_SUCCESS The operation is done correctly.
596 @retval Others The operation fails.
597
598 **/
599 EFI_STATUS
600 SdCardSendTuningBlk (
601 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
602 IN UINT8 Slot
603 )
604 {
605 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
606 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
607 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
608 EFI_STATUS Status;
609 UINT8 TuningBlock[64];
610
611 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
612 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
613 ZeroMem (&Packet, sizeof (Packet));
614
615 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
616 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
617 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
618
619 SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;
620 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
621 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
622 SdMmcCmdBlk.CommandArgument = 0;
623
624 Packet.InDataBuffer = TuningBlock;
625 Packet.InTransferLength = sizeof (TuningBlock);
626
627 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
628
629 return Status;
630 }
631
632 /**
633 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
634
635 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
636 tuning procedure.
637
638 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
639 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
640
641 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
642 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
643 @param[in] Slot The slot number of the SD card to send the command to.
644
645 @retval EFI_SUCCESS The operation is done correctly.
646 @retval Others The operation fails.
647
648 **/
649 EFI_STATUS
650 SdCardTuningClock (
651 IN EFI_PCI_IO_PROTOCOL *PciIo,
652 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
653 IN UINT8 Slot
654 )
655 {
656 EFI_STATUS Status;
657 UINT8 HostCtrl2;
658 UINT8 Retry;
659
660 //
661 // Notify the host that the sampling clock tuning procedure starts.
662 //
663 HostCtrl2 = BIT6;
664 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
665 if (EFI_ERROR (Status)) {
666 return Status;
667 }
668 //
669 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
670 //
671 Retry = 0;
672 do {
673 Status = SdCardSendTuningBlk (PassThru, Slot);
674 if (EFI_ERROR (Status)) {
675 DEBUG ((DEBUG_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));
676 return Status;
677 }
678
679 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
680 if (EFI_ERROR (Status)) {
681 return Status;
682 }
683
684 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
685 break;
686 }
687 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
688 return EFI_SUCCESS;
689 }
690 } while (++Retry < 40);
691
692 DEBUG ((DEBUG_ERROR, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
693 //
694 // Abort the tuning procedure and reset the tuning circuit.
695 //
696 HostCtrl2 = (UINT8)~(BIT6 | BIT7);
697 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
698 if (EFI_ERROR (Status)) {
699 return Status;
700 }
701 return EFI_DEVICE_ERROR;
702 }
703
704 /**
705 Switch the bus width to specified width.
706
707 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
708 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
709
710 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
711 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
712 @param[in] Slot The slot number of the SD card to send the command to.
713 @param[in] Rca The relative device address to be assigned.
714 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
715
716 @retval EFI_SUCCESS The operation is done correctly.
717 @retval Others The operation fails.
718
719 **/
720 EFI_STATUS
721 SdCardSwitchBusWidth (
722 IN EFI_PCI_IO_PROTOCOL *PciIo,
723 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
724 IN UINT8 Slot,
725 IN UINT16 Rca,
726 IN UINT8 BusWidth
727 )
728 {
729 EFI_STATUS Status;
730 UINT32 DevStatus;
731
732 Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);
733 if (EFI_ERROR (Status)) {
734 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
735 return Status;
736 }
737
738 Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);
739 if (EFI_ERROR (Status)) {
740 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));
741 return Status;
742 }
743 //
744 // Check the switch operation is really successful or not.
745 //
746 if ((DevStatus >> 16) != 0) {
747 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
748 return EFI_DEVICE_ERROR;
749 }
750
751 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
752
753 return Status;
754 }
755
756 /**
757 Switch the high speed timing according to request.
758
759 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
760 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
761
762 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
763 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
764 @param[in] Slot The slot number of the SD card to send the command to.
765 @param[in] Rca The relative device address to be assigned.
766 @param[in] S18A The boolean to show if it's a UHS-I SD card.
767
768 @retval EFI_SUCCESS The operation is done correctly.
769 @retval Others The operation fails.
770
771 **/
772 EFI_STATUS
773 SdCardSetBusMode (
774 IN EFI_PCI_IO_PROTOCOL *PciIo,
775 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
776 IN UINT8 Slot,
777 IN UINT16 Rca,
778 IN BOOLEAN S18A
779 )
780 {
781 EFI_STATUS Status;
782 SD_MMC_HC_SLOT_CAP *Capability;
783 UINT32 ClockFreq;
784 UINT8 BusWidth;
785 UINT8 AccessMode;
786 UINT8 HostCtrl1;
787 UINT8 HostCtrl2;
788 UINT8 SwitchResp[64];
789 SD_MMC_HC_PRIVATE_DATA *Private;
790
791 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
792
793 Capability = &Private->Capability[Slot];
794
795 Status = SdCardSelect (PassThru, Slot, Rca);
796 if (EFI_ERROR (Status)) {
797 return Status;
798 }
799
800 BusWidth = 4;
801
802 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, BusWidth);
803 if (EFI_ERROR (Status)) {
804 return Status;
805 }
806 //
807 // Get the supported bus speed from SWITCH cmd return data group #1.
808 //
809 Status = SdCardSwitch (PassThru, Slot, 0xF, 0xF, 0xF, 0xF, FALSE, SwitchResp);
810 if (EFI_ERROR (Status)) {
811 return Status;
812 }
813 //
814 // Calculate supported bus speed/bus width/clock frequency by host and device capability.
815 //
816 ClockFreq = 0;
817 if (S18A && (Capability->Sdr104 != 0) && ((SwitchResp[13] & BIT3) != 0)) {
818 ClockFreq = 208;
819 AccessMode = 3;
820 } else if (S18A && (Capability->Sdr50 != 0) && ((SwitchResp[13] & BIT2) != 0)) {
821 ClockFreq = 100;
822 AccessMode = 2;
823 } else if (S18A && (Capability->Ddr50 != 0) && ((SwitchResp[13] & BIT4) != 0)) {
824 ClockFreq = 50;
825 AccessMode = 4;
826 } else if ((SwitchResp[13] & BIT1) != 0) {
827 ClockFreq = 50;
828 AccessMode = 1;
829 } else {
830 ClockFreq = 25;
831 AccessMode = 0;
832 }
833
834 Status = SdCardSwitch (PassThru, Slot, AccessMode, 0xF, 0xF, 0xF, TRUE, SwitchResp);
835 if (EFI_ERROR (Status)) {
836 return Status;
837 }
838
839 if ((SwitchResp[16] & 0xF) != AccessMode) {
840 DEBUG ((DEBUG_ERROR, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d fails! The Switch response is 0x%1x\n", AccessMode, ClockFreq, BusWidth, SwitchResp[16] & 0xF));
841 return EFI_DEVICE_ERROR;
842 }
843
844 DEBUG ((DEBUG_INFO, "SdCardSetBusMode: Switch to AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));
845
846 //
847 // Set to Hight Speed timing
848 //
849 if (AccessMode == 1) {
850 HostCtrl1 = BIT2;
851 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
852 if (EFI_ERROR (Status)) {
853 return Status;
854 }
855 }
856
857 HostCtrl2 = (UINT8)~0x7;
858 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
859 if (EFI_ERROR (Status)) {
860 return Status;
861 }
862 HostCtrl2 = AccessMode;
863 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
864 if (EFI_ERROR (Status)) {
865 return Status;
866 }
867
868 Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability);
869 if (EFI_ERROR (Status)) {
870 return Status;
871 }
872
873 if ((AccessMode == 3) || ((AccessMode == 2) && (Capability->TuningSDR50 != 0))) {
874 Status = SdCardTuningClock (PciIo, PassThru, Slot);
875 if (EFI_ERROR (Status)) {
876 return Status;
877 }
878 }
879
880 return Status;
881 }
882
883 /**
884 Execute SD device identification procedure.
885
886 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
887
888 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
889 @param[in] Slot The slot number of the SD card to send the command to.
890
891 @retval EFI_SUCCESS There is a SD card.
892 @retval Others There is not a SD card.
893
894 **/
895 EFI_STATUS
896 SdCardIdentification (
897 IN SD_MMC_HC_PRIVATE_DATA *Private,
898 IN UINT8 Slot
899 )
900 {
901 EFI_STATUS Status;
902 EFI_PCI_IO_PROTOCOL *PciIo;
903 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
904 UINT32 Ocr;
905 UINT16 Rca;
906 BOOLEAN Xpc;
907 BOOLEAN S18r;
908 UINT64 MaxCurrent;
909 UINT16 ControllerVer;
910 UINT8 PowerCtrl;
911 UINT32 PresentState;
912 UINT8 HostCtrl2;
913 UINTN Retry;
914
915 PciIo = Private->PciIo;
916 PassThru = &Private->PassThru;
917 //
918 // 1. Send Cmd0 to the device
919 //
920 Status = SdCardReset (PassThru, Slot);
921 if (EFI_ERROR (Status)) {
922 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));
923 return Status;
924 }
925 //
926 // 2. Send Cmd8 to the device
927 //
928 Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);
929 if (EFI_ERROR (Status)) {
930 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));
931 return Status;
932 }
933 //
934 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
935 //
936 Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);
937 if (!EFI_ERROR (Status)) {
938 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
939 return EFI_DEVICE_ERROR;
940 }
941 //
942 // 4. Send Acmd41 with voltage window 0 to the device
943 //
944 Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);
945 if (EFI_ERROR (Status)) {
946 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));
947 return EFI_DEVICE_ERROR;
948 }
949
950 if (Private->Capability[Slot].Voltage33 != 0) {
951 //
952 // Support 3.3V
953 //
954 MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;
955 } else if (Private->Capability[Slot].Voltage30 != 0) {
956 //
957 // Support 3.0V
958 //
959 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;
960 } else if (Private->Capability[Slot].Voltage18 != 0) {
961 //
962 // Support 1.8V
963 //
964 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;
965 } else {
966 ASSERT (FALSE);
967 return EFI_DEVICE_ERROR;
968 }
969
970 if (MaxCurrent >= 150) {
971 Xpc = TRUE;
972 } else {
973 Xpc = FALSE;
974 }
975
976 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
977 if (EFI_ERROR (Status)) {
978 return Status;
979 }
980
981 if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) &&
982 ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) {
983 S18r = TRUE;
984 } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) {
985 S18r = FALSE;
986 } else {
987 ASSERT (FALSE);
988 return EFI_UNSUPPORTED;
989 }
990 //
991 // 5. Repeatly send Acmd41 with supply voltage window to the device.
992 // Note here we only support the cards complied with SD physical
993 // layer simplified spec version 2.0 and version 3.0 and above.
994 //
995 Ocr = 0;
996 Retry = 0;
997 do {
998 Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);
999 if (EFI_ERROR (Status)) {
1000 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));
1001 return EFI_DEVICE_ERROR;
1002 }
1003
1004 if (Retry++ == 100) {
1005 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1006 return EFI_DEVICE_ERROR;
1007 }
1008 gBS->Stall(10 * 1000);
1009 } while ((Ocr & BIT31) == 0);
1010
1011 //
1012 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1013 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1014 // Capabilities register), switch its voltage to 1.8V.
1015 //
1016 if ((Private->Capability[Slot].Sdr50 != 0 ||
1017 Private->Capability[Slot].Sdr104 != 0 ||
1018 Private->Capability[Slot].Ddr50 != 0) &&
1019 ((Ocr & BIT24) != 0)) {
1020 Status = SdCardVoltageSwitch (PassThru, Slot);
1021 if (EFI_ERROR (Status)) {
1022 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));
1023 Status = EFI_DEVICE_ERROR;
1024 goto Error;
1025 } else {
1026 Status = SdMmcHcStopClock (PciIo, Slot);
1027 if (EFI_ERROR (Status)) {
1028 Status = EFI_DEVICE_ERROR;
1029 goto Error;
1030 }
1031
1032 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1033 if (((PresentState >> 20) & 0xF) != 0) {
1034 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));
1035 Status = EFI_DEVICE_ERROR;
1036 goto Error;
1037 }
1038 HostCtrl2 = BIT3;
1039 SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
1040
1041 gBS->Stall (5000);
1042
1043 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
1044 if ((HostCtrl2 & BIT3) == 0) {
1045 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));
1046 Status = EFI_DEVICE_ERROR;
1047 goto Error;
1048 }
1049
1050 SdMmcHcInitClockFreq (PciIo, Slot, Private->Capability[Slot]);
1051
1052 gBS->Stall (1000);
1053
1054 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1055 if (((PresentState >> 20) & 0xF) != 0xF) {
1056 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));
1057 Status = EFI_DEVICE_ERROR;
1058 goto Error;
1059 }
1060 }
1061 DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1062 }
1063
1064 Status = SdCardAllSendCid (PassThru, Slot);
1065 if (EFI_ERROR (Status)) {
1066 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));
1067 return Status;
1068 }
1069
1070 Status = SdCardSetRca (PassThru, Slot, &Rca);
1071 if (EFI_ERROR (Status)) {
1072 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));
1073 return Status;
1074 }
1075 //
1076 // Enter Data Tranfer Mode.
1077 //
1078 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
1079 Private->Slot[Slot].CardType = SdCardType;
1080
1081 Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));
1082
1083 return Status;
1084
1085 Error:
1086 //
1087 // Set SD Bus Power = 0
1088 //
1089 PowerCtrl = (UINT8)~BIT0;
1090 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl);
1091 return EFI_DEVICE_ERROR;
1092 }
1093