]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg: Apply uncrustify changes
[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) 2018, NVIDIA CORPORATION. All rights reserved.
5 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include "SdMmcPciHcDxe.h"
11
12 /**
13 Send command GO_IDLE_STATE to the device to make it go to Idle State.
14
15 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
16
17 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
18 @param[in] Slot The slot number of the SD card to send the command to.
19
20 @retval EFI_SUCCESS The SD device is reset correctly.
21 @retval Others The device reset fails.
22
23 **/
24 EFI_STATUS
25 SdCardReset (
26 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
27 IN UINT8 Slot
28 )
29 {
30 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
31 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
32 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
33 EFI_STATUS Status;
34
35 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
36 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
37 ZeroMem (&Packet, sizeof (Packet));
38
39 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
40 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
41 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
42
43 SdMmcCmdBlk.CommandIndex = SD_GO_IDLE_STATE;
44 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBc;
45
46 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
47
48 return Status;
49 }
50
51 /**
52 Send command SEND_IF_COND to the device to inquiry the SD Memory Card interface
53 condition.
54
55 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
56
57 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
58 @param[in] Slot The slot number of the SD card to send the command to.
59 @param[in] SupplyVoltage The supplied voltage by the host.
60 @param[in] CheckPattern The check pattern to be sent to the device.
61
62 @retval EFI_SUCCESS The operation is done correctly.
63 @retval Others The operation fails.
64
65 **/
66 EFI_STATUS
67 SdCardVoltageCheck (
68 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
69 IN UINT8 Slot,
70 IN UINT8 SupplyVoltage,
71 IN UINT8 CheckPattern
72 )
73 {
74 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
75 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
76 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
77 EFI_STATUS Status;
78
79 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
80 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
81 ZeroMem (&Packet, sizeof (Packet));
82
83 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
84 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
85 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
86
87 SdMmcCmdBlk.CommandIndex = SD_SEND_IF_COND;
88 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
89 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR7;
90 SdMmcCmdBlk.CommandArgument = (SupplyVoltage << 8) | CheckPattern;
91
92 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
93
94 if (!EFI_ERROR (Status)) {
95 if (SdMmcStatusBlk.Resp0 != SdMmcCmdBlk.CommandArgument) {
96 return EFI_DEVICE_ERROR;
97 }
98 }
99
100 return Status;
101 }
102
103 /**
104 Send command SDIO_SEND_OP_COND to the device to see whether it is SDIO device.
105
106 Refer to SDIO Simplified Spec 3 Section 3.2 for details.
107
108 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
109 @param[in] Slot The slot number of the SD card to send the command to.
110 @param[in] VoltageWindow The supply voltage window.
111 @param[in] S18R The boolean to show if it should switch to 1.8v.
112
113 @retval EFI_SUCCESS The operation is done correctly.
114 @retval Others The operation fails.
115
116 **/
117 EFI_STATUS
118 SdioSendOpCond (
119 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
120 IN UINT8 Slot,
121 IN UINT32 VoltageWindow,
122 IN BOOLEAN S18R
123 )
124 {
125 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
126 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
127 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
128 EFI_STATUS Status;
129 UINT32 Switch;
130
131 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
132 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
133 ZeroMem (&Packet, sizeof (Packet));
134
135 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
136 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
137 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
138
139 SdMmcCmdBlk.CommandIndex = SDIO_SEND_OP_COND;
140 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
141 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR4;
142
143 Switch = S18R ? BIT24 : 0;
144
145 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch;
146
147 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
148
149 return Status;
150 }
151
152 /**
153 Send command SD_SEND_OP_COND to the device to see whether it is SDIO device.
154
155 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
156
157 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
158 @param[in] Slot The slot number of the SD card to send the command to.
159 @param[in] Rca The relative device address of addressed device.
160 @param[in] VoltageWindow The supply voltage window.
161 @param[in] S18R The boolean to show if it should switch to 1.8v.
162 @param[in] Xpc The boolean to show if it should provide 0.36w power control.
163 @param[in] Hcs The boolean to show if it support host capacity info.
164 @param[out] Ocr The buffer to store returned OCR register value.
165
166 @retval EFI_SUCCESS The operation is done correctly.
167 @retval Others The operation fails.
168
169 **/
170 EFI_STATUS
171 SdCardSendOpCond (
172 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
173 IN UINT8 Slot,
174 IN UINT16 Rca,
175 IN UINT32 VoltageWindow,
176 IN BOOLEAN S18R,
177 IN BOOLEAN Xpc,
178 IN BOOLEAN Hcs,
179 OUT UINT32 *Ocr
180 )
181 {
182 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
183 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
184 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
185 EFI_STATUS Status;
186 UINT32 Switch;
187 UINT32 MaxPower;
188 UINT32 HostCapacity;
189
190 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
191 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
192 ZeroMem (&Packet, sizeof (Packet));
193
194 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
195 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
196 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
197
198 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
199 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
200 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
201 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
202
203 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
204 if (EFI_ERROR (Status)) {
205 return Status;
206 }
207
208 SdMmcCmdBlk.CommandIndex = SD_SEND_OP_COND;
209 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
210 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3;
211
212 Switch = S18R ? BIT24 : 0;
213 MaxPower = Xpc ? BIT28 : 0;
214 HostCapacity = Hcs ? BIT30 : 0;
215
216 SdMmcCmdBlk.CommandArgument = (VoltageWindow & 0xFFFFFF) | Switch | MaxPower | HostCapacity;
217
218 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
219 if (!EFI_ERROR (Status)) {
220 //
221 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
222 //
223 *Ocr = SdMmcStatusBlk.Resp0;
224 }
225
226 return Status;
227 }
228
229 /**
230 Broadcast command ALL_SEND_CID to the bus to ask all the SD devices to send the
231 data of their CID registers.
232
233 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
234
235 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
236 @param[in] Slot The slot number of the SD card to send the command to.
237
238 @retval EFI_SUCCESS The operation is done correctly.
239 @retval Others The operation fails.
240
241 **/
242 EFI_STATUS
243 SdCardAllSendCid (
244 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
245 IN UINT8 Slot
246 )
247 {
248 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
249 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
250 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
251 EFI_STATUS Status;
252
253 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
254 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
255 ZeroMem (&Packet, sizeof (Packet));
256
257 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
258 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
259 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
260
261 SdMmcCmdBlk.CommandIndex = SD_ALL_SEND_CID;
262 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
263 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
264
265 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
266
267 return Status;
268 }
269
270 /**
271 Send command SET_RELATIVE_ADDR to the SD device to assign a Relative device
272 Address (RCA).
273
274 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
275
276 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
277 @param[in] Slot The slot number of the SD card to send the command to.
278 @param[out] Rca The relative device address to assign.
279
280 @retval EFI_SUCCESS The operation is done correctly.
281 @retval Others The operation fails.
282
283 **/
284 EFI_STATUS
285 SdCardSetRca (
286 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
287 IN UINT8 Slot,
288 OUT UINT16 *Rca
289 )
290 {
291 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
292 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
293 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
294 EFI_STATUS Status;
295
296 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
297 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
298 ZeroMem (&Packet, sizeof (Packet));
299
300 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
301 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
302 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
303
304 SdMmcCmdBlk.CommandIndex = SD_SET_RELATIVE_ADDR;
305 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
306 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR6;
307
308 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
309 if (!EFI_ERROR (Status)) {
310 *Rca = (UINT16)(SdMmcStatusBlk.Resp0 >> 16);
311 }
312
313 return Status;
314 }
315
316 /**
317 Send command SELECT_DESELECT_CARD to the SD device to select/deselect it.
318
319 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
320
321 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
322 @param[in] Slot The slot number of the SD card to send the command to.
323 @param[in] Rca The relative device address of selected device.
324
325 @retval EFI_SUCCESS The operation is done correctly.
326 @retval Others The operation fails.
327
328 **/
329 EFI_STATUS
330 SdCardSelect (
331 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
332 IN UINT8 Slot,
333 IN UINT16 Rca
334 )
335 {
336 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
337 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
338 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
339 EFI_STATUS Status;
340
341 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
342 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
343 ZeroMem (&Packet, sizeof (Packet));
344
345 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
346 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
347 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
348
349 SdMmcCmdBlk.CommandIndex = SD_SELECT_DESELECT_CARD;
350 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
351 if (Rca != 0) {
352 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
353 }
354
355 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
356
357 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
358
359 return Status;
360 }
361
362 /**
363 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
364
365 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
366
367 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
368 @param[in] Slot The slot number of the SD card to send the command to.
369
370 @retval EFI_SUCCESS The operation is done correctly.
371 @retval Others The operation fails.
372
373 **/
374 EFI_STATUS
375 SdCardVoltageSwitch (
376 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
377 IN UINT8 Slot
378 )
379 {
380 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
381 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
382 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
383 EFI_STATUS Status;
384
385 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
386 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
387 ZeroMem (&Packet, sizeof (Packet));
388
389 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
390 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
391 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
392
393 SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;
394 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
395 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
396 SdMmcCmdBlk.CommandArgument = 0;
397
398 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
399
400 return Status;
401 }
402
403 /**
404 Send command SET_BUS_WIDTH to the SD device to set the bus width.
405
406 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
407
408 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
409 @param[in] Slot The slot number of the SD card to send the command to.
410 @param[in] Rca The relative device address of addressed device.
411 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
412
413 @retval EFI_SUCCESS The operation is done correctly.
414 @retval Others The operation fails.
415
416 **/
417 EFI_STATUS
418 SdCardSetBusWidth (
419 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
420 IN UINT8 Slot,
421 IN UINT16 Rca,
422 IN UINT8 BusWidth
423 )
424 {
425 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
426 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
427 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
428 EFI_STATUS Status;
429 UINT8 Value;
430
431 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
432 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
433 ZeroMem (&Packet, sizeof (Packet));
434
435 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
436 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
437 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
438
439 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
440 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
441 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
442 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
443
444 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
445 if (EFI_ERROR (Status)) {
446 return Status;
447 }
448
449 SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;
450 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
451 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
452
453 if (BusWidth == 1) {
454 Value = 0;
455 } else if (BusWidth == 4) {
456 Value = 2;
457 } else {
458 return EFI_INVALID_PARAMETER;
459 }
460
461 SdMmcCmdBlk.CommandArgument = Value & 0x3;
462
463 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
464 return Status;
465 }
466
467 /**
468 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
469
470 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
471
472 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
473 @param[in] Slot The slot number of the SD card to send the command to.
474 @param[in] BusTiming Target bus timing based on which access group value will be set.
475 @param[in] CommandSystem The value for command set group.
476 @param[in] DriverStrength The value for driver strength group.
477 @param[in] PowerLimit The value for power limit group.
478 @param[in] Mode Switch or check function.
479 @param[out] SwitchResp The return switch function status.
480
481 @retval EFI_SUCCESS The operation is done correctly.
482 @retval Others The operation fails.
483
484 **/
485 EFI_STATUS
486 SdCardSwitch (
487 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
488 IN UINT8 Slot,
489 IN SD_MMC_BUS_MODE BusTiming,
490 IN UINT8 CommandSystem,
491 IN SD_DRIVER_STRENGTH_TYPE DriverStrength,
492 IN UINT8 PowerLimit,
493 IN BOOLEAN Mode,
494 OUT UINT8 *SwitchResp
495 )
496 {
497 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
498 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
499 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
500 EFI_STATUS Status;
501 UINT32 ModeValue;
502 UINT8 AccessMode;
503
504 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
505 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
506 ZeroMem (&Packet, sizeof (Packet));
507
508 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
509 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
510 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
511
512 SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;
513 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
514 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
515
516 ModeValue = Mode ? BIT31 : 0;
517
518 switch (BusTiming) {
519 case SdMmcUhsDdr50:
520 AccessMode = 0x4;
521 break;
522 case SdMmcUhsSdr104:
523 AccessMode = 0x3;
524 break;
525 case SdMmcUhsSdr50:
526 AccessMode = 0x2;
527 break;
528 case SdMmcUhsSdr25:
529 case SdMmcSdHs:
530 AccessMode = 0x1;
531 break;
532 case SdMmcUhsSdr12:
533 case SdMmcSdDs:
534 AccessMode = 0;
535 break;
536 default:
537 AccessMode = 0xF;
538 }
539
540 SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((CommandSystem & 0xF) << 4) | \
541 ((DriverStrength & 0xF) << 8) | ((PowerLimit & 0xF) << 12) | \
542 ModeValue;
543
544 Packet.InDataBuffer = SwitchResp;
545 Packet.InTransferLength = 64;
546
547 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
548 if (EFI_ERROR (Status)) {
549 return Status;
550 }
551
552 if (Mode) {
553 if ((((AccessMode & 0xF) != 0xF) && ((SwitchResp[16] & 0xF) != AccessMode)) ||
554 (((CommandSystem & 0xF) != 0xF) && (((SwitchResp[16] >> 4) & 0xF) != CommandSystem)) ||
555 (((DriverStrength & 0xF) != 0xF) && ((SwitchResp[15] & 0xF) != DriverStrength)) ||
556 (((PowerLimit & 0xF) != 0xF) && (((SwitchResp[15] >> 4) & 0xF) != PowerLimit)))
557 {
558 return EFI_DEVICE_ERROR;
559 }
560 }
561
562 return Status;
563 }
564
565 /**
566 Send command SEND_STATUS to the addressed SD device to get its status register.
567
568 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
569
570 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
571 @param[in] Slot The slot number of the SD card to send the command to.
572 @param[in] Rca The relative device address of addressed device.
573 @param[out] DevStatus The returned device status.
574
575 @retval EFI_SUCCESS The operation is done correctly.
576 @retval Others The operation fails.
577
578 **/
579 EFI_STATUS
580 SdCardSendStatus (
581 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
582 IN UINT8 Slot,
583 IN UINT16 Rca,
584 OUT UINT32 *DevStatus
585 )
586 {
587 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
588 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
589 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
590 EFI_STATUS Status;
591
592 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
593 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
594 ZeroMem (&Packet, sizeof (Packet));
595
596 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
597 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
598 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
599
600 SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;
601 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
602 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
603 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
604
605 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
606 if (!EFI_ERROR (Status)) {
607 *DevStatus = SdMmcStatusBlk.Resp0;
608 }
609
610 return Status;
611 }
612
613 /**
614 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
615 detection.
616
617 It may be sent up to 40 times until the host finishes the tuning procedure.
618
619 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
620
621 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
622 @param[in] Slot The slot number of the SD card to send the command to.
623
624 @retval EFI_SUCCESS The operation is done correctly.
625 @retval Others The operation fails.
626
627 **/
628 EFI_STATUS
629 SdCardSendTuningBlk (
630 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
631 IN UINT8 Slot
632 )
633 {
634 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
635 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
636 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
637 EFI_STATUS Status;
638 UINT8 TuningBlock[64];
639
640 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
641 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
642 ZeroMem (&Packet, sizeof (Packet));
643
644 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
645 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
646 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
647
648 SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;
649 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
650 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
651 SdMmcCmdBlk.CommandArgument = 0;
652
653 Packet.InDataBuffer = TuningBlock;
654 Packet.InTransferLength = sizeof (TuningBlock);
655
656 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
657
658 return Status;
659 }
660
661 /**
662 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
663
664 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
665 tuning procedure.
666
667 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
668 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
669
670 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
671 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
672 @param[in] Slot The slot number of the SD card to send the command to.
673
674 @retval EFI_SUCCESS The operation is done correctly.
675 @retval Others The operation fails.
676
677 **/
678 EFI_STATUS
679 SdCardTuningClock (
680 IN EFI_PCI_IO_PROTOCOL *PciIo,
681 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
682 IN UINT8 Slot
683 )
684 {
685 EFI_STATUS Status;
686 UINT8 HostCtrl2;
687 UINT8 Retry;
688
689 //
690 // Notify the host that the sampling clock tuning procedure starts.
691 //
692 HostCtrl2 = BIT6;
693 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
694 if (EFI_ERROR (Status)) {
695 return Status;
696 }
697
698 //
699 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
700 //
701 Retry = 0;
702 do {
703 Status = SdCardSendTuningBlk (PassThru, Slot);
704 if (EFI_ERROR (Status)) {
705 DEBUG ((DEBUG_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));
706 return Status;
707 }
708
709 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
710 if (EFI_ERROR (Status)) {
711 return Status;
712 }
713
714 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
715 break;
716 }
717
718 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
719 return EFI_SUCCESS;
720 }
721 } while (++Retry < 40);
722
723 DEBUG ((DEBUG_ERROR, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
724 //
725 // Abort the tuning procedure and reset the tuning circuit.
726 //
727 HostCtrl2 = (UINT8) ~(BIT6 | BIT7);
728 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
729 if (EFI_ERROR (Status)) {
730 return Status;
731 }
732
733 return EFI_DEVICE_ERROR;
734 }
735
736 /**
737 Switch the bus width to specified width.
738
739 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
740 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
741
742 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
743 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
744 @param[in] Slot The slot number of the SD card to send the command to.
745 @param[in] Rca The relative device address to be assigned.
746 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
747
748 @retval EFI_SUCCESS The operation is done correctly.
749 @retval Others The operation fails.
750
751 **/
752 EFI_STATUS
753 SdCardSwitchBusWidth (
754 IN EFI_PCI_IO_PROTOCOL *PciIo,
755 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
756 IN UINT8 Slot,
757 IN UINT16 Rca,
758 IN UINT8 BusWidth
759 )
760 {
761 EFI_STATUS Status;
762 UINT32 DevStatus;
763
764 Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);
765 if (EFI_ERROR (Status)) {
766 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
767 return Status;
768 }
769
770 Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);
771 if (EFI_ERROR (Status)) {
772 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));
773 return Status;
774 }
775
776 //
777 // Check the switch operation is really successful or not.
778 //
779 if ((DevStatus >> 16) != 0) {
780 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
781 return EFI_DEVICE_ERROR;
782 }
783
784 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
785
786 return Status;
787 }
788
789 /**
790 Check if passed BusTiming is supported in both controller and card.
791
792 @param[in] Private Pointer to controller private data
793 @param[in] SlotIndex Index of the slot in the controller
794 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
795 @param[in] IsInUhsI Flag indicating if link is in UHS-I
796
797 @retval TRUE Both card and controller support given BusTiming
798 @retval FALSE Card or controller doesn't support given BusTiming
799 **/
800 BOOLEAN
801 SdIsBusTimingSupported (
802 IN SD_MMC_HC_PRIVATE_DATA *Private,
803 IN UINT8 SlotIndex,
804 IN UINT8 CardSupportedBusTimings,
805 IN BOOLEAN IsInUhsI,
806 IN SD_MMC_BUS_MODE BusTiming
807 )
808 {
809 SD_MMC_HC_SLOT_CAP *Capability;
810
811 Capability = &Private->Capability[SlotIndex];
812
813 if (IsInUhsI) {
814 switch (BusTiming) {
815 case SdMmcUhsSdr104:
816 if ((Capability->Sdr104 != 0) && ((CardSupportedBusTimings & BIT3) != 0)) {
817 return TRUE;
818 }
819
820 break;
821 case SdMmcUhsDdr50:
822 if ((Capability->Ddr50 != 0) && ((CardSupportedBusTimings & BIT4) != 0)) {
823 return TRUE;
824 }
825
826 break;
827 case SdMmcUhsSdr50:
828 if ((Capability->Sdr50 != 0) && ((CardSupportedBusTimings & BIT2) != 0)) {
829 return TRUE;
830 }
831
832 break;
833 case SdMmcUhsSdr25:
834 if ((CardSupportedBusTimings & BIT1) != 0) {
835 return TRUE;
836 }
837
838 break;
839 case SdMmcUhsSdr12:
840 if ((CardSupportedBusTimings & BIT0) != 0) {
841 return TRUE;
842 }
843
844 break;
845 default:
846 break;
847 }
848 } else {
849 switch (BusTiming) {
850 case SdMmcSdHs:
851 if ((Capability->HighSpeed != 0) && ((CardSupportedBusTimings & BIT1) != 0)) {
852 return TRUE;
853 }
854
855 break;
856 case SdMmcSdDs:
857 if ((CardSupportedBusTimings & BIT0) != 0) {
858 return TRUE;
859 }
860
861 break;
862 default:
863 break;
864 }
865 }
866
867 return FALSE;
868 }
869
870 /**
871 Get the target bus timing to set on the link. This function
872 will try to select highest bus timing supported by card, controller
873 and the driver.
874
875 @param[in] Private Pointer to controller private data
876 @param[in] SlotIndex Index of the slot in the controller
877 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
878 @param[in] IsInUhsI Flag indicating if link is in UHS-I
879
880 @return Bus timing value that should be set on link
881 **/
882 SD_MMC_BUS_MODE
883 SdGetTargetBusTiming (
884 IN SD_MMC_HC_PRIVATE_DATA *Private,
885 IN UINT8 SlotIndex,
886 IN UINT8 CardSupportedBusTimings,
887 IN BOOLEAN IsInUhsI
888 )
889 {
890 SD_MMC_BUS_MODE BusTiming;
891
892 if (IsInUhsI) {
893 BusTiming = SdMmcUhsSdr104;
894 } else {
895 BusTiming = SdMmcSdHs;
896 }
897
898 while (BusTiming > SdMmcSdDs) {
899 if (SdIsBusTimingSupported (Private, SlotIndex, CardSupportedBusTimings, IsInUhsI, BusTiming)) {
900 break;
901 }
902
903 BusTiming--;
904 }
905
906 return BusTiming;
907 }
908
909 /**
910 Get the target bus width to be set on the bus.
911
912 @param[in] Private Pointer to controller private data
913 @param[in] SlotIndex Index of the slot in the controller
914 @param[in] BusTiming Bus timing set on the bus
915
916 @return Bus width to be set on the bus
917 **/
918 UINT8
919 SdGetTargetBusWidth (
920 IN SD_MMC_HC_PRIVATE_DATA *Private,
921 IN UINT8 SlotIndex,
922 IN SD_MMC_BUS_MODE BusTiming
923 )
924 {
925 UINT8 BusWidth;
926 UINT8 PreferredBusWidth;
927
928 PreferredBusWidth = Private->Slot[SlotIndex].OperatingParameters.BusWidth;
929
930 if ((BusTiming == SdMmcSdDs) || (BusTiming == SdMmcSdHs)) {
931 if ((PreferredBusWidth != EDKII_SD_MMC_BUS_WIDTH_IGNORE) &&
932 ((PreferredBusWidth == 1) || (PreferredBusWidth == 4)))
933 {
934 BusWidth = PreferredBusWidth;
935 } else {
936 BusWidth = 4;
937 }
938 } else {
939 //
940 // UHS-I modes support only 4-bit width.
941 // Switch to 4-bit has been done before calling this function anyway so
942 // this is purely informational.
943 //
944 BusWidth = 4;
945 }
946
947 return BusWidth;
948 }
949
950 /**
951 Get the target clock frequency to be set on the bus.
952
953 @param[in] Private Pointer to controller private data
954 @param[in] SlotIndex Index of the slot in the controller
955 @param[in] BusTiming Bus timing to be set on the bus
956
957 @return Value of the clock frequency to be set on bus in MHz
958 **/
959 UINT32
960 SdGetTargetBusClockFreq (
961 IN SD_MMC_HC_PRIVATE_DATA *Private,
962 IN UINT8 SlotIndex,
963 IN SD_MMC_BUS_MODE BusTiming
964 )
965 {
966 UINT32 PreferredClockFreq;
967 UINT32 MaxClockFreq;
968
969 PreferredClockFreq = Private->Slot[SlotIndex].OperatingParameters.ClockFreq;
970
971 switch (BusTiming) {
972 case SdMmcUhsSdr104:
973 MaxClockFreq = 208;
974 break;
975 case SdMmcUhsSdr50:
976 MaxClockFreq = 100;
977 break;
978 case SdMmcUhsDdr50:
979 case SdMmcUhsSdr25:
980 case SdMmcSdHs:
981 MaxClockFreq = 50;
982 break;
983 case SdMmcUhsSdr12:
984 case SdMmcSdDs:
985 default:
986 MaxClockFreq = 25;
987 }
988
989 if ((PreferredClockFreq != EDKII_SD_MMC_CLOCK_FREQ_IGNORE) && (PreferredClockFreq < MaxClockFreq)) {
990 return PreferredClockFreq;
991 } else {
992 return MaxClockFreq;
993 }
994 }
995
996 /**
997 Get the driver strength to be set on bus.
998
999 @param[in] Private Pointer to controller private data
1000 @param[in] SlotIndex Index of the slot in the controller
1001 @param[in] CardSupportedDriverStrengths Bitmask indicating which driver strengths are supported on the card
1002 @param[in] BusTiming Bus timing set on the bus
1003
1004 @return Value of the driver strength to be set on the bus
1005 **/
1006 EDKII_SD_MMC_DRIVER_STRENGTH
1007 SdGetTargetDriverStrength (
1008 IN SD_MMC_HC_PRIVATE_DATA *Private,
1009 IN UINT8 SlotIndex,
1010 IN UINT8 CardSupportedDriverStrengths,
1011 IN SD_MMC_BUS_MODE BusTiming
1012 )
1013 {
1014 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength;
1015 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength;
1016
1017 if ((BusTiming == SdMmcSdDs) || (BusTiming == SdMmcSdHs)) {
1018 DriverStrength.Sd = SdDriverStrengthIgnore;
1019 return DriverStrength;
1020 }
1021
1022 PreferredDriverStrength = Private->Slot[SlotIndex].OperatingParameters.DriverStrength;
1023 DriverStrength.Sd = SdDriverStrengthTypeB;
1024
1025 if ((PreferredDriverStrength.Sd != EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE) &&
1026 (CardSupportedDriverStrengths & (BIT0 << PreferredDriverStrength.Sd)))
1027 {
1028 if (((PreferredDriverStrength.Sd == SdDriverStrengthTypeA) &&
1029 (Private->Capability[SlotIndex].DriverTypeA != 0)) ||
1030 ((PreferredDriverStrength.Sd == SdDriverStrengthTypeC) &&
1031 (Private->Capability[SlotIndex].DriverTypeC != 0)) ||
1032 ((PreferredDriverStrength.Sd == SdDriverStrengthTypeD) &&
1033 (Private->Capability[SlotIndex].DriverTypeD != 0)))
1034 {
1035 DriverStrength.Sd = PreferredDriverStrength.Sd;
1036 }
1037 }
1038
1039 return DriverStrength;
1040 }
1041
1042 /**
1043 Get the target settings for the bus mode.
1044
1045 @param[in] Private Pointer to controller private data
1046 @param[in] SlotIndex Index of the slot in the controller
1047 @param[in] SwitchQueryResp Pointer to switch query response
1048 @param[in] IsInUhsI Flag indicating if link is in UHS-I mode
1049 @param[out] BusMode Target configuration of the bus
1050 **/
1051 VOID
1052 SdGetTargetBusMode (
1053 IN SD_MMC_HC_PRIVATE_DATA *Private,
1054 IN UINT8 SlotIndex,
1055 IN UINT8 *SwitchQueryResp,
1056 IN BOOLEAN IsInUhsI,
1057 OUT SD_MMC_BUS_SETTINGS *BusMode
1058 )
1059 {
1060 BusMode->BusTiming = SdGetTargetBusTiming (Private, SlotIndex, SwitchQueryResp[13], IsInUhsI);
1061 BusMode->BusWidth = SdGetTargetBusWidth (Private, SlotIndex, BusMode->BusTiming);
1062 BusMode->ClockFreq = SdGetTargetBusClockFreq (Private, SlotIndex, BusMode->BusTiming);
1063 BusMode->DriverStrength = SdGetTargetDriverStrength (Private, SlotIndex, SwitchQueryResp[9], BusMode->BusTiming);
1064 }
1065
1066 /**
1067 Switch the high speed timing according to request.
1068
1069 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
1070 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
1071
1072 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1073 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1074 @param[in] Slot The slot number of the SD card to send the command to.
1075 @param[in] Rca The relative device address to be assigned.
1076 @param[in] S18A The boolean to show if it's a UHS-I SD card.
1077
1078 @retval EFI_SUCCESS The operation is done correctly.
1079 @retval Others The operation fails.
1080
1081 **/
1082 EFI_STATUS
1083 SdCardSetBusMode (
1084 IN EFI_PCI_IO_PROTOCOL *PciIo,
1085 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
1086 IN UINT8 Slot,
1087 IN UINT16 Rca,
1088 IN BOOLEAN S18A
1089 )
1090 {
1091 EFI_STATUS Status;
1092 SD_MMC_HC_SLOT_CAP *Capability;
1093 UINT8 HostCtrl1;
1094 UINT8 SwitchResp[64];
1095 SD_MMC_HC_PRIVATE_DATA *Private;
1096 SD_MMC_BUS_SETTINGS BusMode;
1097
1098 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
1099
1100 Capability = &Private->Capability[Slot];
1101
1102 Status = SdCardSelect (PassThru, Slot, Rca);
1103 if (EFI_ERROR (Status)) {
1104 return Status;
1105 }
1106
1107 if (S18A) {
1108 //
1109 // For UHS-I speed modes 4-bit data bus is requiered so we
1110 // switch here irrespective of platform preference.
1111 //
1112 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, 4);
1113 if (EFI_ERROR (Status)) {
1114 return Status;
1115 }
1116 }
1117
1118 //
1119 // Get the supported bus speed from SWITCH cmd return data group #1.
1120 //
1121 Status = SdCardSwitch (PassThru, Slot, 0xFF, 0xF, SdDriverStrengthIgnore, 0xF, FALSE, SwitchResp);
1122 if (EFI_ERROR (Status)) {
1123 return Status;
1124 }
1125
1126 SdGetTargetBusMode (Private, Slot, SwitchResp, S18A, &BusMode);
1127
1128 DEBUG ((
1129 DEBUG_INFO,
1130 "SdCardSetBusMode: Target bus mode: bus timing = %d, bus width = %d, clock freq[MHz] = %d, driver strength = %d\n",
1131 BusMode.BusTiming,
1132 BusMode.BusWidth,
1133 BusMode.ClockFreq,
1134 BusMode.DriverStrength.Sd
1135 ));
1136
1137 if (!S18A) {
1138 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, BusMode.BusWidth);
1139 if (EFI_ERROR (Status)) {
1140 return Status;
1141 }
1142 }
1143
1144 Status = SdCardSwitch (PassThru, Slot, BusMode.BusTiming, 0xF, BusMode.DriverStrength.Sd, 0xF, TRUE, SwitchResp);
1145 if (EFI_ERROR (Status)) {
1146 return Status;
1147 }
1148
1149 Status = SdMmcSetDriverStrength (Private->PciIo, Slot, BusMode.DriverStrength.Sd);
1150 if (EFI_ERROR (Status)) {
1151 return Status;
1152 }
1153
1154 //
1155 // Set to High Speed timing
1156 //
1157 if (BusMode.BusTiming == SdMmcSdHs) {
1158 HostCtrl1 = BIT2;
1159 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
1160 if (EFI_ERROR (Status)) {
1161 return Status;
1162 }
1163 }
1164
1165 Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode.BusTiming);
1166 if (EFI_ERROR (Status)) {
1167 return Status;
1168 }
1169
1170 Status = SdMmcHcClockSupply (Private, Slot, BusMode.BusTiming, FALSE, BusMode.ClockFreq * 1000);
1171 if (EFI_ERROR (Status)) {
1172 return Status;
1173 }
1174
1175 if ((BusMode.BusTiming == SdMmcUhsSdr104) || ((BusMode.BusTiming == SdMmcUhsSdr50) && (Capability->TuningSDR50 != 0))) {
1176 Status = SdCardTuningClock (PciIo, PassThru, Slot);
1177 if (EFI_ERROR (Status)) {
1178 return Status;
1179 }
1180 }
1181
1182 return Status;
1183 }
1184
1185 /**
1186 Execute SD device identification procedure.
1187
1188 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
1189
1190 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1191 @param[in] Slot The slot number of the SD card to send the command to.
1192
1193 @retval EFI_SUCCESS There is a SD card.
1194 @retval Others There is not a SD card.
1195
1196 **/
1197 EFI_STATUS
1198 SdCardIdentification (
1199 IN SD_MMC_HC_PRIVATE_DATA *Private,
1200 IN UINT8 Slot
1201 )
1202 {
1203 EFI_STATUS Status;
1204 EFI_PCI_IO_PROTOCOL *PciIo;
1205 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
1206 UINT32 Ocr;
1207 UINT16 Rca;
1208 BOOLEAN Xpc;
1209 BOOLEAN S18r;
1210 UINT64 MaxCurrent;
1211 UINT16 ControllerVer;
1212 UINT8 PowerCtrl;
1213 UINT32 PresentState;
1214 UINT8 HostCtrl2;
1215 UINTN Retry;
1216
1217 PciIo = Private->PciIo;
1218 PassThru = &Private->PassThru;
1219 //
1220 // 1. Send Cmd0 to the device
1221 //
1222 Status = SdCardReset (PassThru, Slot);
1223 if (EFI_ERROR (Status)) {
1224 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));
1225 return Status;
1226 }
1227
1228 //
1229 // 2. Send Cmd8 to the device
1230 //
1231 Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);
1232 if (EFI_ERROR (Status)) {
1233 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));
1234 return Status;
1235 }
1236
1237 //
1238 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1239 //
1240 Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);
1241 if (!EFI_ERROR (Status)) {
1242 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1243 return EFI_DEVICE_ERROR;
1244 }
1245
1246 //
1247 // 4. Send Acmd41 with voltage window 0 to the device
1248 //
1249 Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);
1250 if (EFI_ERROR (Status)) {
1251 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));
1252 return EFI_DEVICE_ERROR;
1253 }
1254
1255 if (Private->Capability[Slot].Voltage33 != 0) {
1256 //
1257 // Support 3.3V
1258 //
1259 MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;
1260 } else if (Private->Capability[Slot].Voltage30 != 0) {
1261 //
1262 // Support 3.0V
1263 //
1264 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;
1265 } else if (Private->Capability[Slot].Voltage18 != 0) {
1266 //
1267 // Support 1.8V
1268 //
1269 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;
1270 } else {
1271 ASSERT (FALSE);
1272 return EFI_DEVICE_ERROR;
1273 }
1274
1275 if (MaxCurrent >= 150) {
1276 Xpc = TRUE;
1277 } else {
1278 Xpc = FALSE;
1279 }
1280
1281 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
1282 if (EFI_ERROR (Status)) {
1283 return Status;
1284 }
1285
1286 if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) &&
1287 ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420))
1288 {
1289 S18r = TRUE;
1290 } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) {
1291 S18r = FALSE;
1292 } else {
1293 ASSERT (FALSE);
1294 return EFI_UNSUPPORTED;
1295 }
1296
1297 //
1298 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1299 // Note here we only support the cards complied with SD physical
1300 // layer simplified spec version 2.0 and version 3.0 and above.
1301 //
1302 Ocr = 0;
1303 Retry = 0;
1304 do {
1305 Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);
1306 if (EFI_ERROR (Status)) {
1307 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));
1308 return EFI_DEVICE_ERROR;
1309 }
1310
1311 if (Retry++ == 100) {
1312 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1313 return EFI_DEVICE_ERROR;
1314 }
1315
1316 gBS->Stall (10 * 1000);
1317 } while ((Ocr & BIT31) == 0);
1318
1319 //
1320 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1321 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1322 // Capabilities register), switch its voltage to 1.8V.
1323 //
1324 if (((Private->Capability[Slot].Sdr50 != 0) ||
1325 (Private->Capability[Slot].Sdr104 != 0) ||
1326 (Private->Capability[Slot].Ddr50 != 0)) &&
1327 ((Ocr & BIT24) != 0))
1328 {
1329 Status = SdCardVoltageSwitch (PassThru, Slot);
1330 if (EFI_ERROR (Status)) {
1331 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));
1332 Status = EFI_DEVICE_ERROR;
1333 goto Error;
1334 } else {
1335 Status = SdMmcHcStopClock (PciIo, Slot);
1336 if (EFI_ERROR (Status)) {
1337 Status = EFI_DEVICE_ERROR;
1338 goto Error;
1339 }
1340
1341 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1342 if (((PresentState >> 20) & 0xF) != 0) {
1343 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));
1344 Status = EFI_DEVICE_ERROR;
1345 goto Error;
1346 }
1347
1348 HostCtrl2 = BIT3;
1349 SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
1350
1351 gBS->Stall (5000);
1352
1353 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
1354 if ((HostCtrl2 & BIT3) == 0) {
1355 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));
1356 Status = EFI_DEVICE_ERROR;
1357 goto Error;
1358 }
1359
1360 Status = SdMmcHcStartSdClock (PciIo, Slot);
1361 if (EFI_ERROR (Status)) {
1362 goto Error;
1363 }
1364
1365 gBS->Stall (1000);
1366
1367 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1368 if (((PresentState >> 20) & 0xF) != 0xF) {
1369 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));
1370 Status = EFI_DEVICE_ERROR;
1371 goto Error;
1372 }
1373 }
1374
1375 DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1376 }
1377
1378 Status = SdCardAllSendCid (PassThru, Slot);
1379 if (EFI_ERROR (Status)) {
1380 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));
1381 return Status;
1382 }
1383
1384 Status = SdCardSetRca (PassThru, Slot, &Rca);
1385 if (EFI_ERROR (Status)) {
1386 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));
1387 return Status;
1388 }
1389
1390 //
1391 // Enter Data Tranfer Mode.
1392 //
1393 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
1394 Private->Slot[Slot].CardType = SdCardType;
1395
1396 Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));
1397
1398 return Status;
1399
1400 Error:
1401 //
1402 // Set SD Bus Power = 0
1403 //
1404 PowerCtrl = (UINT8) ~BIT0;
1405 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl);
1406 return EFI_DEVICE_ERROR;
1407 }