]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdDevice.c
MdeModulePkg/SdMmcHcDxe: Implement revision 3 of SdMmcOverrideProtocol
[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 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
355
356 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
357
358 return Status;
359 }
360
361 /**
362 Send command VOLTAGE_SWITCH to the SD device to switch the voltage of the device.
363
364 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
365
366 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
367 @param[in] Slot The slot number of the SD card to send the command to.
368
369 @retval EFI_SUCCESS The operation is done correctly.
370 @retval Others The operation fails.
371
372 **/
373 EFI_STATUS
374 SdCardVoltageSwitch (
375 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
376 IN UINT8 Slot
377 )
378 {
379 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
380 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
381 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
382 EFI_STATUS Status;
383
384 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
385 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
386 ZeroMem (&Packet, sizeof (Packet));
387
388 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
389 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
390 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
391
392 SdMmcCmdBlk.CommandIndex = SD_VOLTAGE_SWITCH;
393 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
394 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
395 SdMmcCmdBlk.CommandArgument = 0;
396
397 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
398
399 return Status;
400 }
401
402 /**
403 Send command SET_BUS_WIDTH to the SD device to set the bus width.
404
405 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
406
407 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
408 @param[in] Slot The slot number of the SD card to send the command to.
409 @param[in] Rca The relative device address of addressed device.
410 @param[in] BusWidth The bus width to be set, it could be 1 or 4.
411
412 @retval EFI_SUCCESS The operation is done correctly.
413 @retval Others The operation fails.
414
415 **/
416 EFI_STATUS
417 SdCardSetBusWidth (
418 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
419 IN UINT8 Slot,
420 IN UINT16 Rca,
421 IN UINT8 BusWidth
422 )
423 {
424 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
425 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
426 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
427 EFI_STATUS Status;
428 UINT8 Value;
429
430 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
431 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
432 ZeroMem (&Packet, sizeof (Packet));
433
434 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
435 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
436 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
437
438 SdMmcCmdBlk.CommandIndex = SD_APP_CMD;
439 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
440 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
441 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
442
443 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
444 if (EFI_ERROR (Status)) {
445 return Status;
446 }
447
448 SdMmcCmdBlk.CommandIndex = SD_SET_BUS_WIDTH;
449 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
450 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
451
452 if (BusWidth == 1) {
453 Value = 0;
454 } else if (BusWidth == 4) {
455 Value = 2;
456 } else {
457 return EFI_INVALID_PARAMETER;
458 }
459
460 SdMmcCmdBlk.CommandArgument = Value & 0x3;
461
462 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
463 return Status;
464 }
465
466 /**
467 Send command SWITCH_FUNC to the SD device to check switchable function or switch card function.
468
469 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
470
471 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
472 @param[in] Slot The slot number of the SD card to send the command to.
473 @param[in] BusTiming Target bus timing based on which access group value will be set.
474 @param[in] CommandSystem The value for command set group.
475 @param[in] DriverStrength The value for driver strength group.
476 @param[in] PowerLimit The value for power limit group.
477 @param[in] Mode Switch or check function.
478 @param[out] SwitchResp The return switch function status.
479
480 @retval EFI_SUCCESS The operation is done correctly.
481 @retval Others The operation fails.
482
483 **/
484 EFI_STATUS
485 SdCardSwitch (
486 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
487 IN UINT8 Slot,
488 IN SD_MMC_BUS_MODE BusTiming,
489 IN UINT8 CommandSystem,
490 IN SD_DRIVER_STRENGTH_TYPE DriverStrength,
491 IN UINT8 PowerLimit,
492 IN BOOLEAN Mode,
493 OUT UINT8 *SwitchResp
494 )
495 {
496 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
497 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
498 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
499 EFI_STATUS Status;
500 UINT32 ModeValue;
501 UINT8 AccessMode;
502
503 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
504 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
505 ZeroMem (&Packet, sizeof (Packet));
506
507 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
508 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
509 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
510
511 SdMmcCmdBlk.CommandIndex = SD_SWITCH_FUNC;
512 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
513 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
514
515 ModeValue = Mode ? BIT31 : 0;
516
517 switch (BusTiming) {
518 case SdMmcUhsDdr50:
519 AccessMode = 0x4;
520 break;
521 case SdMmcUhsSdr104:
522 AccessMode = 0x3;
523 break;
524 case SdMmcUhsSdr50:
525 AccessMode = 0x2;
526 break;
527 case SdMmcUhsSdr25:
528 case SdMmcSdHs:
529 AccessMode = 0x1;
530 break;
531 case SdMmcUhsSdr12:
532 case SdMmcSdDs:
533 AccessMode = 0;
534 break;
535 default:
536 AccessMode = 0xF;
537 }
538
539 SdMmcCmdBlk.CommandArgument = (AccessMode & 0xF) | ((CommandSystem & 0xF) << 4) | \
540 ((DriverStrength & 0xF) << 8) | ((PowerLimit & 0xF) << 12) | \
541 ModeValue;
542
543 Packet.InDataBuffer = SwitchResp;
544 Packet.InTransferLength = 64;
545
546 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
547 if (EFI_ERROR (Status)) {
548 return Status;
549 }
550
551 if (Mode) {
552 if ((((AccessMode & 0xF) != 0xF) && ((SwitchResp[16] & 0xF) != AccessMode)) ||
553 (((CommandSystem & 0xF) != 0xF) && (((SwitchResp[16] >> 4) & 0xF) != CommandSystem)) ||
554 (((DriverStrength & 0xF) != 0xF) && ((SwitchResp[15] & 0xF) != DriverStrength)) ||
555 (((PowerLimit & 0xF) != 0xF) && (((SwitchResp[15] >> 4) & 0xF) != PowerLimit))) {
556 return EFI_DEVICE_ERROR;
557 }
558 }
559
560 return Status;
561 }
562
563 /**
564 Send command SEND_STATUS to the addressed SD device to get its status register.
565
566 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
567
568 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
569 @param[in] Slot The slot number of the SD card to send the command to.
570 @param[in] Rca The relative device address of addressed device.
571 @param[out] DevStatus The returned device status.
572
573 @retval EFI_SUCCESS The operation is done correctly.
574 @retval Others The operation fails.
575
576 **/
577 EFI_STATUS
578 SdCardSendStatus (
579 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
580 IN UINT8 Slot,
581 IN UINT16 Rca,
582 OUT UINT32 *DevStatus
583 )
584 {
585 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
586 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
587 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
588 EFI_STATUS Status;
589
590 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
591 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
592 ZeroMem (&Packet, sizeof (Packet));
593
594 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
595 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
596 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
597
598 SdMmcCmdBlk.CommandIndex = SD_SEND_STATUS;
599 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
600 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
601 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
602
603 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
604 if (!EFI_ERROR (Status)) {
605 *DevStatus = SdMmcStatusBlk.Resp0;
606 }
607
608 return Status;
609 }
610
611 /**
612 Send command SEND_TUNING_BLOCK to the SD device for HS200 optimal sampling point
613 detection.
614
615 It may be sent up to 40 times until the host finishes the tuning procedure.
616
617 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 for details.
618
619 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
620 @param[in] Slot The slot number of the SD card to send the command to.
621
622 @retval EFI_SUCCESS The operation is done correctly.
623 @retval Others The operation fails.
624
625 **/
626 EFI_STATUS
627 SdCardSendTuningBlk (
628 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
629 IN UINT8 Slot
630 )
631 {
632 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
633 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
634 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
635 EFI_STATUS Status;
636 UINT8 TuningBlock[64];
637
638 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
639 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
640 ZeroMem (&Packet, sizeof (Packet));
641
642 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
643 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
644 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
645
646 SdMmcCmdBlk.CommandIndex = SD_SEND_TUNING_BLOCK;
647 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
648 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
649 SdMmcCmdBlk.CommandArgument = 0;
650
651 Packet.InDataBuffer = TuningBlock;
652 Packet.InTransferLength = sizeof (TuningBlock);
653
654 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
655
656 return Status;
657 }
658
659 /**
660 Tunning the sampling point of SDR104 or SDR50 bus speed mode.
661
662 Command SD_SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
663 tuning procedure.
664
665 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
666 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
667
668 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
669 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
670 @param[in] Slot The slot number of the SD card to send the command to.
671
672 @retval EFI_SUCCESS The operation is done correctly.
673 @retval Others The operation fails.
674
675 **/
676 EFI_STATUS
677 SdCardTuningClock (
678 IN EFI_PCI_IO_PROTOCOL *PciIo,
679 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
680 IN UINT8 Slot
681 )
682 {
683 EFI_STATUS Status;
684 UINT8 HostCtrl2;
685 UINT8 Retry;
686
687 //
688 // Notify the host that the sampling clock tuning procedure starts.
689 //
690 HostCtrl2 = BIT6;
691 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
692 if (EFI_ERROR (Status)) {
693 return Status;
694 }
695 //
696 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
697 //
698 Retry = 0;
699 do {
700 Status = SdCardSendTuningBlk (PassThru, Slot);
701 if (EFI_ERROR (Status)) {
702 DEBUG ((DEBUG_ERROR, "SdCardSendTuningBlk: Send tuning block fails with %r\n", Status));
703 return Status;
704 }
705
706 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
707 if (EFI_ERROR (Status)) {
708 return Status;
709 }
710
711 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
712 break;
713 }
714 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
715 return EFI_SUCCESS;
716 }
717 } while (++Retry < 40);
718
719 DEBUG ((DEBUG_ERROR, "SdCardTuningClock: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
720 //
721 // Abort the tuning procedure and reset the tuning circuit.
722 //
723 HostCtrl2 = (UINT8)~(BIT6 | BIT7);
724 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
725 if (EFI_ERROR (Status)) {
726 return Status;
727 }
728 return EFI_DEVICE_ERROR;
729 }
730
731 /**
732 Switch the bus width to specified width.
733
734 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
735 SD Host Controller Simplified Spec 3.0 section Figure 3-7 for details.
736
737 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
738 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
739 @param[in] Slot The slot number of the SD card to send the command to.
740 @param[in] Rca The relative device address to be assigned.
741 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
742
743 @retval EFI_SUCCESS The operation is done correctly.
744 @retval Others The operation fails.
745
746 **/
747 EFI_STATUS
748 SdCardSwitchBusWidth (
749 IN EFI_PCI_IO_PROTOCOL *PciIo,
750 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
751 IN UINT8 Slot,
752 IN UINT16 Rca,
753 IN UINT8 BusWidth
754 )
755 {
756 EFI_STATUS Status;
757 UINT32 DevStatus;
758
759 Status = SdCardSetBusWidth (PassThru, Slot, Rca, BusWidth);
760 if (EFI_ERROR (Status)) {
761 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
762 return Status;
763 }
764
765 Status = SdCardSendStatus (PassThru, Slot, Rca, &DevStatus);
766 if (EFI_ERROR (Status)) {
767 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: Send status fails with %r\n", Status));
768 return Status;
769 }
770 //
771 // Check the switch operation is really successful or not.
772 //
773 if ((DevStatus >> 16) != 0) {
774 DEBUG ((DEBUG_ERROR, "SdCardSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
775 return EFI_DEVICE_ERROR;
776 }
777
778 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
779
780 return Status;
781 }
782
783 /**
784 Check if passed BusTiming is supported in both controller and card.
785
786 @param[in] Private Pointer to controller private data
787 @param[in] SlotIndex Index of the slot in the controller
788 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
789 @param[in] IsInUhsI Flag indicating if link is in UHS-I
790
791 @retval TRUE Both card and controller support given BusTiming
792 @retval FALSE Card or controller doesn't support given BusTiming
793 **/
794 BOOLEAN
795 SdIsBusTimingSupported (
796 IN SD_MMC_HC_PRIVATE_DATA *Private,
797 IN UINT8 SlotIndex,
798 IN UINT8 CardSupportedBusTimings,
799 IN BOOLEAN IsInUhsI,
800 IN SD_MMC_BUS_MODE BusTiming
801 )
802 {
803 SD_MMC_HC_SLOT_CAP *Capability;
804
805 Capability = &Private->Capability[SlotIndex];
806
807 if (IsInUhsI) {
808 switch (BusTiming) {
809 case SdMmcUhsSdr104:
810 if ((Capability->Sdr104 != 0) && ((CardSupportedBusTimings & BIT3) != 0)) {
811 return TRUE;
812 }
813 break;
814 case SdMmcUhsDdr50:
815 if ((Capability->Ddr50 != 0) && ((CardSupportedBusTimings & BIT4) != 0)) {
816 return TRUE;
817 }
818 break;
819 case SdMmcUhsSdr50:
820 if ((Capability->Sdr50 != 0) && ((CardSupportedBusTimings & BIT2) != 0)) {
821 return TRUE;
822 }
823 break;
824 case SdMmcUhsSdr25:
825 if ((CardSupportedBusTimings & BIT1) != 0) {
826 return TRUE;
827 }
828 break;
829 case SdMmcUhsSdr12:
830 if ((CardSupportedBusTimings & BIT0) != 0) {
831 return TRUE;
832 }
833 break;
834 default:
835 break;
836 }
837 } else {
838 switch (BusTiming) {
839 case SdMmcSdHs:
840 if ((Capability->HighSpeed != 0) && (CardSupportedBusTimings & BIT1) != 0) {
841 return TRUE;
842 }
843 break;
844 case SdMmcSdDs:
845 if ((CardSupportedBusTimings & BIT0) != 0) {
846 return TRUE;
847 }
848 break;
849 default:
850 break;
851 }
852 }
853
854 return FALSE;
855 }
856
857 /**
858 Get the target bus timing to set on the link. This function
859 will try to select highest bus timing supported by card, controller
860 and the driver.
861
862 @param[in] Private Pointer to controller private data
863 @param[in] SlotIndex Index of the slot in the controller
864 @param[in] CardSupportedBusTimings Bitmask indicating which bus timings are supported by card
865 @param[in] IsInUhsI Flag indicating if link is in UHS-I
866
867 @return Bus timing value that should be set on link
868 **/
869 SD_MMC_BUS_MODE
870 SdGetTargetBusTiming (
871 IN SD_MMC_HC_PRIVATE_DATA *Private,
872 IN UINT8 SlotIndex,
873 IN UINT8 CardSupportedBusTimings,
874 IN BOOLEAN IsInUhsI
875 )
876 {
877 SD_MMC_BUS_MODE BusTiming;
878
879 if (IsInUhsI) {
880 BusTiming = SdMmcUhsSdr104;
881 } else {
882 BusTiming = SdMmcSdHs;
883 }
884
885 while (BusTiming > SdMmcSdDs) {
886 if (SdIsBusTimingSupported (Private, SlotIndex, CardSupportedBusTimings, IsInUhsI, BusTiming)) {
887 break;
888 }
889 BusTiming--;
890 }
891
892 return BusTiming;
893 }
894
895 /**
896 Get the target bus width to be set on the bus.
897
898 @param[in] Private Pointer to controller private data
899 @param[in] SlotIndex Index of the slot in the controller
900 @param[in] BusTiming Bus timing set on the bus
901
902 @return Bus width to be set on the bus
903 **/
904 UINT8
905 SdGetTargetBusWidth (
906 IN SD_MMC_HC_PRIVATE_DATA *Private,
907 IN UINT8 SlotIndex,
908 IN SD_MMC_BUS_MODE BusTiming
909 )
910 {
911 UINT8 BusWidth;
912 UINT8 PreferredBusWidth;
913
914 PreferredBusWidth = Private->Slot[SlotIndex].OperatingParameters.BusWidth;
915
916 if (BusTiming == SdMmcSdDs || BusTiming == SdMmcSdHs) {
917 if (PreferredBusWidth != EDKII_SD_MMC_BUS_WIDTH_IGNORE &&
918 (PreferredBusWidth == 1 || PreferredBusWidth == 4)) {
919 BusWidth = PreferredBusWidth;
920 } else {
921 BusWidth = 4;
922 }
923 } else {
924 //
925 // UHS-I modes support only 4-bit width.
926 // Switch to 4-bit has been done before calling this function anyway so
927 // this is purely informational.
928 //
929 BusWidth = 4;
930 }
931
932 return BusWidth;
933 }
934
935 /**
936 Get the target clock frequency to be set on the bus.
937
938 @param[in] Private Pointer to controller private data
939 @param[in] SlotIndex Index of the slot in the controller
940 @param[in] BusTiming Bus timing to be set on the bus
941
942 @return Value of the clock frequency to be set on bus in MHz
943 **/
944 UINT32
945 SdGetTargetBusClockFreq (
946 IN SD_MMC_HC_PRIVATE_DATA *Private,
947 IN UINT8 SlotIndex,
948 IN SD_MMC_BUS_MODE BusTiming
949 )
950 {
951 UINT32 PreferredClockFreq;
952 UINT32 MaxClockFreq;
953
954 PreferredClockFreq = Private->Slot[SlotIndex].OperatingParameters.ClockFreq;
955
956 switch (BusTiming) {
957 case SdMmcUhsSdr104:
958 MaxClockFreq = 208;
959 break;
960 case SdMmcUhsSdr50:
961 MaxClockFreq = 100;
962 break;
963 case SdMmcUhsDdr50:
964 case SdMmcUhsSdr25:
965 case SdMmcSdHs:
966 MaxClockFreq = 50;
967 break;
968 case SdMmcUhsSdr12:
969 case SdMmcSdDs:
970 default:
971 MaxClockFreq = 25;
972 }
973
974 if (PreferredClockFreq != EDKII_SD_MMC_CLOCK_FREQ_IGNORE && PreferredClockFreq < MaxClockFreq) {
975 return PreferredClockFreq;
976 } else {
977 return MaxClockFreq;
978 }
979 }
980
981 /**
982 Get the driver strength to be set on bus.
983
984 @param[in] Private Pointer to controller private data
985 @param[in] SlotIndex Index of the slot in the controller
986 @param[in] CardSupportedDriverStrengths Bitmask indicating which driver strengths are supported on the card
987 @param[in] BusTiming Bus timing set on the bus
988
989 @return Value of the driver strength to be set on the bus
990 **/
991 EDKII_SD_MMC_DRIVER_STRENGTH
992 SdGetTargetDriverStrength (
993 IN SD_MMC_HC_PRIVATE_DATA *Private,
994 IN UINT8 SlotIndex,
995 IN UINT8 CardSupportedDriverStrengths,
996 IN SD_MMC_BUS_MODE BusTiming
997 )
998 {
999 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength;
1000 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength;
1001
1002 if (BusTiming == SdMmcSdDs || BusTiming == SdMmcSdHs) {
1003 DriverStrength.Sd = SdDriverStrengthIgnore;
1004 return DriverStrength;
1005 }
1006
1007 PreferredDriverStrength = Private->Slot[SlotIndex].OperatingParameters.DriverStrength;
1008 DriverStrength.Sd = SdDriverStrengthTypeB;
1009
1010 if (PreferredDriverStrength.Sd != EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE &&
1011 (CardSupportedDriverStrengths & (BIT0 << PreferredDriverStrength.Sd))) {
1012
1013 if ((PreferredDriverStrength.Sd == SdDriverStrengthTypeA &&
1014 (Private->Capability[SlotIndex].DriverTypeA != 0)) ||
1015 (PreferredDriverStrength.Sd == SdDriverStrengthTypeC &&
1016 (Private->Capability[SlotIndex].DriverTypeC != 0)) ||
1017 (PreferredDriverStrength.Sd == SdDriverStrengthTypeD &&
1018 (Private->Capability[SlotIndex].DriverTypeD != 0))) {
1019 DriverStrength.Sd = PreferredDriverStrength.Sd;
1020 }
1021 }
1022
1023 return DriverStrength;
1024 }
1025
1026 /**
1027 Get the target settings for the bus mode.
1028
1029 @param[in] Private Pointer to controller private data
1030 @param[in] SlotIndex Index of the slot in the controller
1031 @param[in] SwitchQueryResp Pointer to switch query response
1032 @param[in] IsInUhsI Flag indicating if link is in UHS-I mode
1033 @param[out] BusMode Target configuration of the bus
1034 **/
1035 VOID
1036 SdGetTargetBusMode (
1037 IN SD_MMC_HC_PRIVATE_DATA *Private,
1038 IN UINT8 SlotIndex,
1039 IN UINT8 *SwitchQueryResp,
1040 IN BOOLEAN IsInUhsI,
1041 OUT SD_MMC_BUS_SETTINGS *BusMode
1042 )
1043 {
1044 BusMode->BusTiming = SdGetTargetBusTiming (Private, SlotIndex, SwitchQueryResp[13], IsInUhsI);
1045 BusMode->BusWidth = SdGetTargetBusWidth (Private, SlotIndex, BusMode->BusTiming);
1046 BusMode->ClockFreq = SdGetTargetBusClockFreq (Private, SlotIndex, BusMode->BusTiming);
1047 BusMode->DriverStrength = SdGetTargetDriverStrength (Private, SlotIndex, SwitchQueryResp[9], BusMode->BusTiming);
1048 }
1049
1050 /**
1051 Switch the high speed timing according to request.
1052
1053 Refer to SD Physical Layer Simplified Spec 4.1 Section 4.7 and
1054 SD Host Controller Simplified Spec 3.0 section Figure 2-29 for details.
1055
1056 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1057 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1058 @param[in] Slot The slot number of the SD card to send the command to.
1059 @param[in] Rca The relative device address to be assigned.
1060 @param[in] S18A The boolean to show if it's a UHS-I SD card.
1061
1062 @retval EFI_SUCCESS The operation is done correctly.
1063 @retval Others The operation fails.
1064
1065 **/
1066 EFI_STATUS
1067 SdCardSetBusMode (
1068 IN EFI_PCI_IO_PROTOCOL *PciIo,
1069 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
1070 IN UINT8 Slot,
1071 IN UINT16 Rca,
1072 IN BOOLEAN S18A
1073 )
1074 {
1075 EFI_STATUS Status;
1076 SD_MMC_HC_SLOT_CAP *Capability;
1077 UINT8 HostCtrl1;
1078 UINT8 SwitchResp[64];
1079 SD_MMC_HC_PRIVATE_DATA *Private;
1080 SD_MMC_BUS_SETTINGS BusMode;
1081
1082 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
1083
1084 Capability = &Private->Capability[Slot];
1085
1086 Status = SdCardSelect (PassThru, Slot, Rca);
1087 if (EFI_ERROR (Status)) {
1088 return Status;
1089 }
1090
1091 if (S18A) {
1092 //
1093 // For UHS-I speed modes 4-bit data bus is requiered so we
1094 // switch here irrespective of platform preference.
1095 //
1096 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, 4);
1097 if (EFI_ERROR (Status)) {
1098 return Status;
1099 }
1100 }
1101
1102 //
1103 // Get the supported bus speed from SWITCH cmd return data group #1.
1104 //
1105 Status = SdCardSwitch (PassThru, Slot, 0xFF, 0xF, SdDriverStrengthIgnore, 0xF, FALSE, SwitchResp);
1106 if (EFI_ERROR (Status)) {
1107 return Status;
1108 }
1109
1110 SdGetTargetBusMode (Private, Slot, SwitchResp, S18A, &BusMode);
1111
1112 DEBUG ((DEBUG_INFO, "SdCardSetBusMode: Target bus mode: bus timing = %d, bus width = %d, clock freq[MHz] = %d, driver strength = %d\n",
1113 BusMode.BusTiming, BusMode.BusWidth, BusMode.ClockFreq, BusMode.DriverStrength.Sd));
1114
1115 if (!S18A) {
1116 Status = SdCardSwitchBusWidth (PciIo, PassThru, Slot, Rca, BusMode.BusWidth);
1117 if (EFI_ERROR (Status)) {
1118 return Status;
1119 }
1120 }
1121
1122 Status = SdCardSwitch (PassThru, Slot, BusMode.BusTiming, 0xF, BusMode.DriverStrength.Sd, 0xF, TRUE, SwitchResp);
1123 if (EFI_ERROR (Status)) {
1124 return Status;
1125 }
1126
1127 Status = SdMmcSetDriverStrength (Private->PciIo, Slot, BusMode.DriverStrength.Sd);
1128 if (EFI_ERROR (Status)) {
1129 return Status;
1130 }
1131
1132 //
1133 // Set to High Speed timing
1134 //
1135 if (BusMode.BusTiming == SdMmcSdHs) {
1136 HostCtrl1 = BIT2;
1137 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
1138 if (EFI_ERROR (Status)) {
1139 return Status;
1140 }
1141 }
1142
1143 Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusMode.BusTiming);
1144 if (EFI_ERROR (Status)) {
1145 return Status;
1146 }
1147
1148 Status = SdMmcHcClockSupply (PciIo, Slot, BusMode.ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
1149 if (EFI_ERROR (Status)) {
1150 return Status;
1151 }
1152
1153 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
1154 Status = mOverride->NotifyPhase (
1155 Private->ControllerHandle,
1156 Slot,
1157 EdkiiSdMmcSwitchClockFreqPost,
1158 &BusMode.BusTiming
1159 );
1160 if (EFI_ERROR (Status)) {
1161 DEBUG ((
1162 DEBUG_ERROR,
1163 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
1164 __FUNCTION__,
1165 Status
1166 ));
1167 return Status;
1168 }
1169 }
1170
1171 if ((BusMode.BusTiming == SdMmcUhsSdr104) || ((BusMode.BusTiming == SdMmcUhsSdr50) && (Capability->TuningSDR50 != 0))) {
1172 Status = SdCardTuningClock (PciIo, PassThru, Slot);
1173 if (EFI_ERROR (Status)) {
1174 return Status;
1175 }
1176 }
1177
1178 return Status;
1179 }
1180
1181 /**
1182 Execute SD device identification procedure.
1183
1184 Refer to SD Physical Layer Simplified Spec 4.1 Section 3.6 for details.
1185
1186 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1187 @param[in] Slot The slot number of the SD card to send the command to.
1188
1189 @retval EFI_SUCCESS There is a SD card.
1190 @retval Others There is not a SD card.
1191
1192 **/
1193 EFI_STATUS
1194 SdCardIdentification (
1195 IN SD_MMC_HC_PRIVATE_DATA *Private,
1196 IN UINT8 Slot
1197 )
1198 {
1199 EFI_STATUS Status;
1200 EFI_PCI_IO_PROTOCOL *PciIo;
1201 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
1202 UINT32 Ocr;
1203 UINT16 Rca;
1204 BOOLEAN Xpc;
1205 BOOLEAN S18r;
1206 UINT64 MaxCurrent;
1207 UINT16 ControllerVer;
1208 UINT8 PowerCtrl;
1209 UINT32 PresentState;
1210 UINT8 HostCtrl2;
1211 UINTN Retry;
1212
1213 PciIo = Private->PciIo;
1214 PassThru = &Private->PassThru;
1215 //
1216 // 1. Send Cmd0 to the device
1217 //
1218 Status = SdCardReset (PassThru, Slot);
1219 if (EFI_ERROR (Status)) {
1220 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd0 fails with %r\n", Status));
1221 return Status;
1222 }
1223 //
1224 // 2. Send Cmd8 to the device
1225 //
1226 Status = SdCardVoltageCheck (PassThru, Slot, 0x1, 0xFF);
1227 if (EFI_ERROR (Status)) {
1228 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing Cmd8 fails with %r\n", Status));
1229 return Status;
1230 }
1231 //
1232 // 3. Send SDIO Cmd5 to the device to the SDIO device OCR register.
1233 //
1234 Status = SdioSendOpCond (PassThru, Slot, 0, FALSE);
1235 if (!EFI_ERROR (Status)) {
1236 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found SDIO device, ignore it as we don't support\n"));
1237 return EFI_DEVICE_ERROR;
1238 }
1239 //
1240 // 4. Send Acmd41 with voltage window 0 to the device
1241 //
1242 Status = SdCardSendOpCond (PassThru, Slot, 0, 0, FALSE, FALSE, FALSE, &Ocr);
1243 if (EFI_ERROR (Status)) {
1244 DEBUG ((DEBUG_INFO, "SdCardIdentification: Executing SdCardSendOpCond fails with %r\n", Status));
1245 return EFI_DEVICE_ERROR;
1246 }
1247
1248 if (Private->Capability[Slot].Voltage33 != 0) {
1249 //
1250 // Support 3.3V
1251 //
1252 MaxCurrent = ((UINT32)Private->MaxCurrent[Slot] & 0xFF) * 4;
1253 } else if (Private->Capability[Slot].Voltage30 != 0) {
1254 //
1255 // Support 3.0V
1256 //
1257 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 8) & 0xFF) * 4;
1258 } else if (Private->Capability[Slot].Voltage18 != 0) {
1259 //
1260 // Support 1.8V
1261 //
1262 MaxCurrent = (((UINT32)Private->MaxCurrent[Slot] >> 16) & 0xFF) * 4;
1263 } else {
1264 ASSERT (FALSE);
1265 return EFI_DEVICE_ERROR;
1266 }
1267
1268 if (MaxCurrent >= 150) {
1269 Xpc = TRUE;
1270 } else {
1271 Xpc = FALSE;
1272 }
1273
1274 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (ControllerVer), &ControllerVer);
1275 if (EFI_ERROR (Status)) {
1276 return Status;
1277 }
1278
1279 if (((ControllerVer & 0xFF) >= SD_MMC_HC_CTRL_VER_300) &&
1280 ((ControllerVer & 0xFF) <= SD_MMC_HC_CTRL_VER_420)) {
1281 S18r = TRUE;
1282 } else if (((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_100) || ((ControllerVer & 0xFF) == SD_MMC_HC_CTRL_VER_200)) {
1283 S18r = FALSE;
1284 } else {
1285 ASSERT (FALSE);
1286 return EFI_UNSUPPORTED;
1287 }
1288 //
1289 // 5. Repeatly send Acmd41 with supply voltage window to the device.
1290 // Note here we only support the cards complied with SD physical
1291 // layer simplified spec version 2.0 and version 3.0 and above.
1292 //
1293 Ocr = 0;
1294 Retry = 0;
1295 do {
1296 Status = SdCardSendOpCond (PassThru, Slot, 0, Ocr, S18r, Xpc, TRUE, &Ocr);
1297 if (EFI_ERROR (Status)) {
1298 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails with %r Ocr %x, S18r %x, Xpc %x\n", Status, Ocr, S18r, Xpc));
1299 return EFI_DEVICE_ERROR;
1300 }
1301
1302 if (Retry++ == 100) {
1303 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SdCardSendOpCond fails too many times\n"));
1304 return EFI_DEVICE_ERROR;
1305 }
1306 gBS->Stall(10 * 1000);
1307 } while ((Ocr & BIT31) == 0);
1308
1309 //
1310 // 6. If the S18A bit is set and the Host Controller supports 1.8V signaling
1311 // (One of support bits is set to 1: SDR50, SDR104 or DDR50 in the
1312 // Capabilities register), switch its voltage to 1.8V.
1313 //
1314 if ((Private->Capability[Slot].Sdr50 != 0 ||
1315 Private->Capability[Slot].Sdr104 != 0 ||
1316 Private->Capability[Slot].Ddr50 != 0) &&
1317 ((Ocr & BIT24) != 0)) {
1318 Status = SdCardVoltageSwitch (PassThru, Slot);
1319 if (EFI_ERROR (Status)) {
1320 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardVoltageSwitch fails with %r\n", Status));
1321 Status = EFI_DEVICE_ERROR;
1322 goto Error;
1323 } else {
1324 Status = SdMmcHcStopClock (PciIo, Slot);
1325 if (EFI_ERROR (Status)) {
1326 Status = EFI_DEVICE_ERROR;
1327 goto Error;
1328 }
1329
1330 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1331 if (((PresentState >> 20) & 0xF) != 0) {
1332 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x\n", PresentState));
1333 Status = EFI_DEVICE_ERROR;
1334 goto Error;
1335 }
1336 HostCtrl2 = BIT3;
1337 SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
1338
1339 gBS->Stall (5000);
1340
1341 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
1342 if ((HostCtrl2 & BIT3) == 0) {
1343 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with HostCtrl2 = 0x%x\n", HostCtrl2));
1344 Status = EFI_DEVICE_ERROR;
1345 goto Error;
1346 }
1347
1348 SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
1349
1350 gBS->Stall (1000);
1351
1352 SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);
1353 if (((PresentState >> 20) & 0xF) != 0xF) {
1354 DEBUG ((DEBUG_ERROR, "SdCardIdentification: SwitchVoltage fails with PresentState = 0x%x, It should be 0xF\n", PresentState));
1355 Status = EFI_DEVICE_ERROR;
1356 goto Error;
1357 }
1358 }
1359 DEBUG ((DEBUG_INFO, "SdCardIdentification: Switch to 1.8v signal voltage success\n"));
1360 }
1361
1362 Status = SdCardAllSendCid (PassThru, Slot);
1363 if (EFI_ERROR (Status)) {
1364 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardAllSendCid fails with %r\n", Status));
1365 return Status;
1366 }
1367
1368 Status = SdCardSetRca (PassThru, Slot, &Rca);
1369 if (EFI_ERROR (Status)) {
1370 DEBUG ((DEBUG_ERROR, "SdCardIdentification: Executing SdCardSetRca fails with %r\n", Status));
1371 return Status;
1372 }
1373 //
1374 // Enter Data Tranfer Mode.
1375 //
1376 DEBUG ((DEBUG_INFO, "SdCardIdentification: Found a SD device at slot [%d]\n", Slot));
1377 Private->Slot[Slot].CardType = SdCardType;
1378
1379 Status = SdCardSetBusMode (PciIo, PassThru, Slot, Rca, ((Ocr & BIT24) != 0));
1380
1381 return Status;
1382
1383 Error:
1384 //
1385 // Set SD Bus Power = 0
1386 //
1387 PowerCtrl = (UINT8)~BIT0;
1388 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, sizeof (PowerCtrl), &PowerCtrl);
1389 return EFI_DEVICE_ERROR;
1390 }
1391