]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/SdMmc: Add EDKII SD/MMC stack
[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, 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 Send command SEND_CSD to the SD device to get the data of the CSD register.
323
324 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
325
326 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
327 @param[in] Slot The slot number of the SD card to send the command to.
328 @param[in] Rca The relative device address of selected device.
329 @param[out] Csd The buffer to store the content of the CSD register.
330 Note the caller should ignore the lowest byte of this
331 buffer as the content of this byte is meaningless even
332 if the operation succeeds.
333
334 @retval EFI_SUCCESS The operation is done correctly.
335 @retval Others The operation fails.
336
337 **/
338 EFI_STATUS
339 SdCardGetCsd (
340 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
341 IN UINT8 Slot,
342 IN UINT16 Rca,
343 OUT SD_CSD *Csd
344 )
345 {
346 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
347 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
348 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
349 EFI_STATUS Status;
350
351 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
352 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
353 ZeroMem (&Packet, sizeof (Packet));
354
355 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
356 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
357 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
358
359 SdMmcCmdBlk.CommandIndex = SD_SEND_CSD;
360 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
361 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
362 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
363
364 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
365 if (!EFI_ERROR (Status)) {
366 //
367 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
368 //
369 CopyMem (((UINT8*)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (SD_CSD) - 1);
370 }
371
372 return Status;
373 }
374
375 /**
376 Send command SEND_CSD to the SD device to get the data of the CSD register.
377
378 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
379
380 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
381 @param[in] Slot The slot number of the SD card to send the command to.
382 @param[in] Rca The relative device address of selected device.
383 @param[out] Scr The buffer to store the content of the SCR register.
384
385 @retval EFI_SUCCESS The operation is done correctly.
386 @retval Others The operation fails.
387
388 **/
389 EFI_STATUS
390 SdCardGetScr (
391 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
392 IN UINT8 Slot,
393 IN UINT16 Rca,
394 OUT SD_SCR *Scr
395 )
396 {
397 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
398 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
399 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
400 EFI_STATUS Status;
401
402 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
403 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
404 ZeroMem (&Packet, sizeof (Packet));
405
406 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
407 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
408 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
409
410 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
411 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
412 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
413 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
414
415 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
416 if (EFI_ERROR (Status)) {
417 return Status;
418 }
419
420 SdMmcCmdBlk.CommandIndex = SD_SEND_SCR;
421 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
422 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
423
424 Packet.InDataBuffer = Scr;
425 Packet.InTransferLength = sizeof (SD_SCR);
426
427 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
428
429 return Status;
430 }
431
432 /**
433 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
434
435 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
436
437 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
438 @param[in] Slot The slot number of the SD card to send the command to.
439 @param[in] Rca The relative device address of selected device.
440
441 @retval EFI_SUCCESS The operation is done correctly.
442 @retval Others The operation fails.
443
444 **/
445 EFI_STATUS
446 SdCardSelect (
447 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
448 IN UINT8 Slot,
449 IN UINT16 Rca
450 )
451 {
452 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
453 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
454 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
455 EFI_STATUS Status;
456
457 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
458 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
459 ZeroMem (&Packet, sizeof (Packet));
460
461 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
462 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
463 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
464
465 SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD;
466 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
467 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
468 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
469
470 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
471
472 return Status;
473 }
474
475 /**
476 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
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
483 @retval EFI_SUCCESS The operation is done correctly.
484 @retval Others The operation fails.
485
486 **/
487 EFI_STATUS
488 SdCardVoltageSwitch (
489 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
490 IN UINT8 Slot
491 )
492 {
493 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
494 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
495 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
496 EFI_STATUS Status;
497
498 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
499 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
500 ZeroMem (&Packet, sizeof (Packet));
501
502 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
503 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
504 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
505
506 SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;
507 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
508 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
509 SdMmcCmdBlk.CommandArgument = 0;
510
511 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
512
513 return Status;
514 }
515
516 /**
517 Send command SET_BUS_WIDTH to the SD device to set the bus width.
518
519 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
520
521 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
522 @param[in] Slot The slot number of the SD card to send the command to.
523 @param[in] Rca The relative device address of addressed device.
524 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
525
526 @retval EFI_SUCCESS The operation is done correctly.
527 @retval Others The operation fails.
528
529 **/
530 EFI_STATUS
531 SdCardSetBusWidth (
532 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
533 IN UINT8 Slot,
534 IN UINT16 Rca,
535 IN UINT8 BusWidth
536 )
537 {
538 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
539 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
540 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
541 EFI_STATUS Status;
542 UINT8 Value;
543
544 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
545 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
546 ZeroMem (&Packet, sizeof (Packet));
547
548 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
549 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
550 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
551
552 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
553 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
554 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
555 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
556
557 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
558 if (EFI_ERROR (Status)) {
559 return Status;
560 }
561
562 SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;
563 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
564 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
565
566 if (BusWidth == 1) {
567 Value = 0;
568 } else if (BusWidth == 4) {
569 Value = 2;
570 } else {
571 return EFI_INVALID_PARAMETER;
572 }
573
574 SdMmcCmdBlk.CommandArgument = Value & 0x3;
575
576 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
577 return Status;
578 }
579
580 /**
581 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
582
583 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
584
585 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
586 @param[in] Slot The slot number of the SD card to send the command to.
587 @param[in] AccessMode The value for access mode group.
588 @param[in] CommandSystem The value for command set group.
589 @param[in] DriveStrength The value for drive length group.
590 @param[in] PowerLimit The value for power limit group.
591 @param[in] Mode Switch or check function.
592
593 @retval EFI_SUCCESS The operation is done correctly.
594 @retval Others The operation fails.
595
596 **/
597 EFI_STATUS
598 SdCardSwitch (
599 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
600 IN UINT8 Slot,
601 IN UINT8 AccessMode,
602 IN UINT8 CommandSystem,
603 IN UINT8 DriveStrength,
604 IN UINT8 PowerLimit,
605 IN BOOLEAN Mode
606 )
607 {
608 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
609 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
610 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
611 EFI_STATUS Status;
612 UINT32 ModeValue;
613 UINT8 Data[64];
614
615 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
616 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
617 ZeroMem (&Packet, sizeof (Packet));
618
619 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
620 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
621 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
622
623 SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;
624 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
625 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
626
627 ModeValue = Mode ? BIT31 : 0;
628 SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((PowerLimit & 0xF) << 4) | \
629 ((DriveStrength & 0xF) << 8) | ((DriveStrength & 0xF) << 12) | \
630 ModeValue;
631
632 Packet.InDataBuffer = Data;
633 Packet.InTransferLength = sizeof (Data);
634
635 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
636
637 return Status;
638 }
639
640 /**
641 Send command SEND_STATUS to the addressed SD device to get its status register.
642
643 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
644
645 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
646 @param[in] Slot The slot number of the SD card to send the command to.
647 @param[in] Rca The relative device address of addressed device.
648 @param[out] DevStatus The returned device status.
649
650 @retval EFI_SUCCESS The operation is done correctly.
651 @retval Others The operation fails.
652
653 **/
654 EFI_STATUS
655 SdCardSendStatus (
656 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
657 IN UINT8 Slot,
658 IN UINT16 Rca,
659 OUT UINT32 *DevStatus
660 )
661 {
662 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
663 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
664 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
665 EFI_STATUS Status;
666
667 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
668 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
669 ZeroMem (&Packet, sizeof (Packet));
670
671 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
672 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
673 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
674
675 SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;
676 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
677 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
678 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
679
680 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
681 if (!EFI_ERROR (Status)) {
682 *DevStatus = SdMmcStatusBlk.Resp0;
683 }
684
685 return Status;
686 }
687
688 /**
689 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
690 detection.
691
692 It may be sent up to 40 times until the host finishes the tuning procedure.
693
694 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
695
696 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
697 @param[in] Slot The slot number of the SD card to send the command to.
698
699 @retval EFI_SUCCESS The operation is done correctly.
700 @retval Others The operation fails.
701
702 **/
703 EFI_STATUS
704 SdCardSendTuningBlk (
705 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
706 IN UINT8 Slot
707 )
708 {
709 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
710 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
711 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
712 EFI_STATUS Status;
713 UINT8 TuningBlock[64];
714
715 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
716 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
717 ZeroMem (&Packet, sizeof (Packet));
718
719 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
720 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
721 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
722
723 SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;
724 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
725 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
726 SdMmcCmdBlk.CommandArgument = 0;
727
728 Packet.InDataBuffer = TuningBlock;
729 Packet.InTransferLength = sizeof (TuningBlock);
730
731 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
732
733 return Status;
734 }
735
736 /**
737 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
738
739 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
740 tuning procedure.
741
742 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
743 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
744
745 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
746 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
747 @param[in] Slot The slot number of the SD card to send the command to.
748
749 @retval EFI_SUCCESS The operation is done correctly.
750 @retval Others The operation fails.
751
752 **/
753 EFI_STATUS
754 SdCardTuningClock (
755 IN EFI_PCI_IO_PROTOCOL *PciIo,
756 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
757 IN UINT8 Slot
758 )
759 {
760 EFI_STATUS Status;
761 UINT8 HostCtrl2;
762 UINT8 Retry;
763
764 //
765 // Notify the host that the sampling clock tuning procedure starts.
766 //
767 HostCtrl2 = BIT6;
768 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
769 if (EFI_ERROR (Status)) {
770 return Status;
771 }
772 //
773 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
774 //
775 Retry = 0;
776 do {
777 Status = SdCardSendTuningBlk (PassThru, Slot);
778 if (EFI_ERROR (Status)) {
779 DEBUG ((EFI_D_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));
780 return Status;
781 }
782
783 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
784 if (EFI_ERROR (Status)) {
785 return Status;
786 }
787
788 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
789 break;
790 }
791 } while (++Retry < 40);
792
793 if (Retry == 40) {
794 Status = EFI_TIMEOUT;
795 DEBUG ((EFI_D_ERROR, "SdCardTuningClock: Send tuning block exceeds 40 times\n"));
796 }
797
798 return Status;
799 }
800
801 /**
802 Switch the bus width to specified width.
803
804 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
805 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
806
807 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
808 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
809 @param[in] Slot The slot number of the SD card to send the command to.
810 @param[in] Rca The relative device address to be assigned.
811 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
812
813 @retval EFI_SUCCESS The operation is done correctly.
814 @retval Others The operation fails.
815
816 **/
817 EFI_STATUS
818 SdCardSwitchBusWidth (
819 IN EFI_PCI_IO_PROTOCOL *PciIo,
820 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
821 IN UINT8 Slot,
822 IN UINT16 Rca,
823 IN UINT8 BusWidth
824 )
825 {
826 EFI_STATUS Status;
827 UINT32 DevStatus;
828
829 Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);
830 if (EFI_ERROR (Status)) {
831 DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
832 return Status;
833 }
834
835 Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);
836 if (EFI_ERROR (Status)) {
837 DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));
838 return Status;
839 }
840 //
841 // Check the switch operation is really successful or not.
842 //
843 if ((DevStatus >> 16) != 0) {
844 DEBUG ((EFI_D_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
845 return EFI_DEVICE_ERROR;
846 }
847
848 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
849
850 return Status;
851 }
852
853 /**
854 Switch the high speed timing according to request.
855
856 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
857 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
858
859 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
860 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
861 @param[in] Slot The slot number of the SD card to send the command to.
862 @param[in] Rca The relative device address to be assigned.
863 @param[in] S18A The boolean to show if it's a UHS-I SD card.
864
865 @retval EFI_SUCCESS The operation is done correctly.
866 @retval Others The operation fails.
867
868 **/
869 EFI_STATUS
870 SdCardSetBusMode (
871 IN EFI_PCI_IO_PROTOCOL *PciIo,
872 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
873 IN UINT8 Slot,
874 IN UINT16 Rca,
875 IN BOOLEAN S18A
876 )
877 {
878 EFI_STATUS Status;
879 SD_MMC_HC_SLOT_CAP *Capability;
880 UINT32 ClockFreq;
881 UINT8 BusWidth;
882 UINT8 AccessMode;
883 UINT8 HostCtrl1;
884 UINT8 HostCtrl2;
885 SD_MMC_HC_PRIVATE_DATA *Private;
886
887 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
888
889 Capability = &Private->Capability[Slot];
890
891 Status = SdCardSelect (PassThru, Slot, Rca);
892 if (EFI_ERROR (Status)) {
893 return Status;
894 }
895
896 BusWidth = 4;
897
898 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, BusWidth);
899 if (EFI_ERROR (Status)) {
900 return Status;
901 }
902
903 //
904 // Calculate supported bus speed/bus width/clock frequency.
905 //
906 ClockFreq = 0;
907 if (S18A && (Capability->Sdr104 != 0)) {
908 ClockFreq = 208;
909 AccessMode = 3;
910 } else if (S18A && (Capability->Sdr50 != 0)) {
911 ClockFreq = 100;
912 AccessMode = 2;
913 } else if (S18A && (Capability->Ddr50 != 0)) {
914 ClockFreq = 50;
915 AccessMode = 4;
916 } else {
917 ClockFreq = 50;
918 AccessMode = 1;
919 }
920
921 DEBUG ((EFI_D_INFO, "SdCardSetBusMode: AccessMode %d ClockFreq %d BusWidth %d\n", AccessMode, ClockFreq, BusWidth));
922
923 Status = SdCardSwitch (PassThru, Slot, AccessMode, 0, 0, 0, TRUE);
924 if (EFI_ERROR (Status)) {
925 return Status;
926 }
927
928 //
929 // Set to Hight Speed timing
930 //
931 if (AccessMode == 1) {
932 HostCtrl1 = BIT2;
933 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
934 if (EFI_ERROR (Status)) {
935 return Status;
936 }
937 }
938
939 HostCtrl2 = (UINT8)~0x7;
940 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
941 if (EFI_ERROR (Status)) {
942 return Status;
943 }
944 HostCtrl2 = AccessMode;
945 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
946 if (EFI_ERROR (Status)) {
947 return Status;
948 }
949
950 Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, *Capability);
951 if (EFI_ERROR (Status)) {
952 return Status;
953 }
954
955 if ((AccessMode == 3) || ((AccessMode == 2) && (Capability->TuningSDR50 != 0))) {
956 Status = SdCardTuningClock (PciIo, PassThru, Slot);
957 if (EFI_ERROR (Status)) {
958 return Status;
959 }
960 }
961
962 return Status;
963 }
964
965 /**
966 Execute SD device identification procedure.
967
968 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
969
970 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
971 @param[in] Slot The slot number of the SD card to send the command to.
972
973 @retval EFI_SUCCESS There is a SD card.
974 @retval Others There is not a SD card.
975
976 **/
977 EFI_STATUS
978 SdCardIdentification (
979 IN SD_MMC_HC_PRIVATE_DATA *Private,
980 IN UINT8 Slot
981 )
982 {
983 EFI_STATUS Status;
984 EFI_PCI_IO_PROTOCOL *PciIo;
985 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
986 UINT32 Ocr;
987 UINT16 Rca;
988 BOOLEAN Xpc;
989 BOOLEAN S18r;
990 UINT64 MaxCurrent;
991 UINT16 ControllerVer;
992 UINT8 PowerCtrl;
993 UINT32 PresentState;
994 UINT8 HostCtrl2;
995
996 PciIo = Private->PciIo;
997 PassThru = &Private->PassThru;
998 //
999 // 1. Send Cmd0 to the device
1000 //
1001 Status = SdCardReset (PassThru, Slot);
1002 if (EFI_ERROR (Status)) {
1003 DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));
1004 return Status;
1005 }
1006 //
1007 // 2. Send Cmd8 to the device
1008 //
1009 Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);
1010 if (EFI_ERROR (Status)) {
1011 DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));
1012 return Status;
1013 }
1014 //
1015 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1016 //
1017 Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);
1018 if (!EFI_ERROR (Status)) {
1019 DEBUG ((EFI_D_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1020 return EFI_DEVICE_ERROR;
1021 }
1022 //
1023 // 4. Send Acmd41 with voltage window 0 to the device
1024 //
1025 Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);
1026 if (EFI_ERROR (Status)) {
1027 DEBUG ((EFI_D_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));
1028 return EFI_DEVICE_ERROR;
1029 }
1030
1031 if (Private->Capability[Slot].Voltage33 != 0) {
1032 //
1033 // Support 3.3V
1034 //
1035 MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;
1036 } else if (Private->Capability[Slot].Voltage30 != 0) {
1037 //
1038 // Support 3.0V
1039 //
1040 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;
1041 } else if (Private->Capability[Slot].Voltage18 != 0) {
1042 //
1043 // Support 1.8V
1044 //
1045 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;
1046 } else {
1047 ASSERT (FALSE);
1048 return EFI_DEVICE_ERROR;
1049 }
1050
1051 if (MaxCurrent >= 150) {
1052 Xpc = TRUE;
1053 } else {
1054 Xpc = FALSE;
1055 }
1056
1057 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
1058 if (EFI_ERROR (Status)) {
1059 return Status;
1060 }
1061
1062 if ((ControllerVer & 0xFF) == 2) {
1063 S18r = TRUE;
1064 } else if (((ControllerVer & 0xFF) == 0) || ((ControllerVer & 0xFF) == 1)) {
1065 S18r = FALSE;
1066 } else {
1067 ASSERT (FALSE);
1068 return EFI_UNSUPPORTED;
1069 }
1070 //
1071 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1072 // Note here we only support the cards complied with SD physical
1073 // layer simplified spec version 2.0 and version 3.0 and above.
1074 //
1075 do {
1076 Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);
1077 if (EFI_ERROR (Status)) {
1078 DEBUG ((EFI_D_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));
1079 return EFI_DEVICE_ERROR;
1080 }
1081 } while ((Ocr & BIT31) == 0);
1082
1083 //
1084 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1085 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1086 // Capabilities register), switch its voltage to 1.8V.
1087 //
1088 if ((Private->Capability[Slot].Sdr50 != 0 ||
1089 Private->Capability[Slot].Sdr104 != 0 ||
1090 Private->Capability[Slot].Ddr50 != 0) &&
1091 ((Ocr & BIT24) != 0)) {
1092 Status = SdCardVoltageSwitch (PassThru, Slot);
1093 if (EFI_ERROR (Status)) {
1094 DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));
1095 Status = EFI_DEVICE_ERROR;
1096 goto Error;
1097 } else {
1098 Status = SdMmcHcStopClock (PciIo, Slot);
1099 if (EFI_ERROR (Status)) {
1100 Status = EFI_DEVICE_ERROR;
1101 goto Error;
1102 }
1103
1104 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1105 if (((PresentState >> 20) & 0xF) != 0) {
1106 DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));
1107 Status = EFI_DEVICE_ERROR;
1108 goto Error;
1109 }
1110 HostCtrl2 = BIT3;
1111 SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
1112
1113 gBS->Stall (5000);
1114
1115 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
1116 if ((HostCtrl2 & BIT3) == 0) {
1117 DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));
1118 Status = EFI_DEVICE_ERROR;
1119 goto Error;
1120 }
1121
1122 SdMmcHcInitClockFreq (PciIo, Slot, Private->Capability[Slot]);
1123
1124 gBS->Stall (1);
1125
1126 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1127 if (((PresentState >> 20) & 0xF) != 0xF) {
1128 DEBUG ((EFI_D_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));
1129 Status = EFI_DEVICE_ERROR;
1130 goto Error;
1131 }
1132 }
1133 DEBUG ((EFI_D_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1134 }
1135
1136 Status = SdCardAllSendCid (PassThru, Slot);
1137 if (EFI_ERROR (Status)) {
1138 DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));
1139 return Status;
1140 }
1141
1142 Status = SdCardSetRca (PassThru, Slot, &Rca);
1143 if (EFI_ERROR (Status)) {
1144 DEBUG ((EFI_D_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));
1145 return Status;
1146 }
1147 //
1148 // Enter Data Tranfer Mode.
1149 //
1150 DEBUG ((EFI_D_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
1151 Private->Slot[Slot].CardType = SdCardType;
1152
1153 Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));
1154
1155 return Status;
1156
1157 Error:
1158 //
1159 // Set SD Bus Power = 0
1160 //
1161 PowerCtrl = (UINT8)~BIT0;
1162 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl);
1163 return EFI_DEVICE_ERROR;
1164 }
1165