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