]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
MdeModulePkg: Apply uncrustify changes
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / EmmcDevice.c
1 /** @file
2 This file provides some helper functions which are specific for EMMC 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 (CMD0 with argument of 0x00000000) to the device to
14 make it go to Idle State.
15
16 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
17
18 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
19 @param[in] Slot The slot number of the SD card to send the command to.
20
21 @retval EFI_SUCCESS The EMMC device is reset correctly.
22 @retval Others The device reset fails.
23
24 **/
25 EFI_STATUS
26 EmmcReset (
27 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
28 IN UINT8 Slot
29 )
30 {
31 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
32 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
33 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
34 EFI_STATUS Status;
35
36 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
37 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
38 ZeroMem (&Packet, sizeof (Packet));
39
40 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
41 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
42 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
43
44 SdMmcCmdBlk.CommandIndex = EMMC_GO_IDLE_STATE;
45 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBc;
46 SdMmcCmdBlk.ResponseType = 0;
47 SdMmcCmdBlk.CommandArgument = 0;
48
49 gBS->Stall (1000);
50
51 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
52
53 return Status;
54 }
55
56 /**
57 Send command SEND_OP_COND to the EMMC device to get the data of the OCR register.
58
59 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
60
61 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
62 @param[in] Slot The slot number of the SD card to send the command to.
63 @param[in, out] Argument On input, the argument of SEND_OP_COND is to send to the device.
64 On output, the argument is the value of OCR register.
65
66 @retval EFI_SUCCESS The operation is done correctly.
67 @retval Others The operation fails.
68
69 **/
70 EFI_STATUS
71 EmmcGetOcr (
72 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
73 IN UINT8 Slot,
74 IN OUT UINT32 *Argument
75 )
76 {
77 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
78 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
79 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
80 EFI_STATUS Status;
81
82 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
83 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
84 ZeroMem (&Packet, sizeof (Packet));
85
86 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
87 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
88 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
89
90 SdMmcCmdBlk.CommandIndex = EMMC_SEND_OP_COND;
91 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
92 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR3;
93 SdMmcCmdBlk.CommandArgument = *Argument;
94
95 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
96 if (!EFI_ERROR (Status)) {
97 //
98 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
99 //
100 *Argument = SdMmcStatusBlk.Resp0;
101 }
102
103 return Status;
104 }
105
106 /**
107 Broadcast command ALL_SEND_CID to the bus to ask all the EMMC devices to send the
108 data of their CID registers.
109
110 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
111
112 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
113 @param[in] Slot The slot number of the SD card to send the command to.
114
115 @retval EFI_SUCCESS The operation is done correctly.
116 @retval Others The operation fails.
117
118 **/
119 EFI_STATUS
120 EmmcGetAllCid (
121 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
122 IN UINT8 Slot
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
130 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
131 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
132 ZeroMem (&Packet, sizeof (Packet));
133
134 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
135 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
136 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
137
138 SdMmcCmdBlk.CommandIndex = EMMC_ALL_SEND_CID;
139 SdMmcCmdBlk.CommandType = SdMmcCommandTypeBcr;
140 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
141 SdMmcCmdBlk.CommandArgument = 0;
142
143 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
144
145 return Status;
146 }
147
148 /**
149 Send command SET_RELATIVE_ADDR to the EMMC device to assign a Relative device
150 Address (RCA).
151
152 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
153
154 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
155 @param[in] Slot The slot number of the SD card to send the command to.
156 @param[in] Rca The relative device address to be assigned.
157
158 @retval EFI_SUCCESS The operation is done correctly.
159 @retval Others The operation fails.
160
161 **/
162 EFI_STATUS
163 EmmcSetRca (
164 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
165 IN UINT8 Slot,
166 IN UINT16 Rca
167 )
168 {
169 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
170 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
171 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
172 EFI_STATUS Status;
173
174 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
175 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
176 ZeroMem (&Packet, sizeof (Packet));
177
178 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
179 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
180 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
181
182 SdMmcCmdBlk.CommandIndex = EMMC_SET_RELATIVE_ADDR;
183 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
184 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
185 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
186
187 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
188
189 return Status;
190 }
191
192 /**
193 Send command SEND_CSD to the EMMC device to get the data of the CSD register.
194
195 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
196
197 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
198 @param[in] Slot The slot number of the SD card to send the command to.
199 @param[in] Rca The relative device address of selected device.
200 @param[out] Csd The buffer to store the content of the CSD register.
201 Note the caller should ignore the lowest byte of this
202 buffer as the content of this byte is meaningless even
203 if the operation succeeds.
204
205 @retval EFI_SUCCESS The operation is done correctly.
206 @retval Others The operation fails.
207
208 **/
209 EFI_STATUS
210 EmmcGetCsd (
211 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
212 IN UINT8 Slot,
213 IN UINT16 Rca,
214 OUT EMMC_CSD *Csd
215 )
216 {
217 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
218 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
219 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
220 EFI_STATUS Status;
221
222 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
223 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
224 ZeroMem (&Packet, sizeof (Packet));
225
226 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
227 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
228 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
229
230 SdMmcCmdBlk.CommandIndex = EMMC_SEND_CSD;
231 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
232 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR2;
233 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
234
235 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
236 if (!EFI_ERROR (Status)) {
237 //
238 // For details, refer to SD Host Controller Simplified Spec 3.0 Table 2-12.
239 //
240 CopyMem (((UINT8 *)Csd) + 1, &SdMmcStatusBlk.Resp0, sizeof (EMMC_CSD) - 1);
241 }
242
243 return Status;
244 }
245
246 /**
247 Send command SELECT_DESELECT_CARD to the EMMC device to select/deselect it.
248
249 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
250
251 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
252 @param[in] Slot The slot number of the SD card to send the command to.
253 @param[in] Rca The relative device address of selected device.
254
255 @retval EFI_SUCCESS The operation is done correctly.
256 @retval Others The operation fails.
257
258 **/
259 EFI_STATUS
260 EmmcSelect (
261 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
262 IN UINT8 Slot,
263 IN UINT16 Rca
264 )
265 {
266 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
267 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
268 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
269 EFI_STATUS Status;
270
271 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
272 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
273 ZeroMem (&Packet, sizeof (Packet));
274
275 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
276 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
277 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
278
279 SdMmcCmdBlk.CommandIndex = EMMC_SELECT_DESELECT_CARD;
280 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
281 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
282 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
283
284 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
285
286 return Status;
287 }
288
289 /**
290 Send command SEND_EXT_CSD to the EMMC device to get the data of the EXT_CSD register.
291
292 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
293
294 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
295 @param[in] Slot The slot number of the SD card to send the command to.
296 @param[out] ExtCsd The buffer to store the content of the EXT_CSD register.
297
298 @retval EFI_SUCCESS The operation is done correctly.
299 @retval Others The operation fails.
300
301 **/
302 EFI_STATUS
303 EmmcGetExtCsd (
304 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
305 IN UINT8 Slot,
306 OUT EMMC_EXT_CSD *ExtCsd
307 )
308 {
309 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
310 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
311 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
312 EFI_STATUS Status;
313
314 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
315 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
316 ZeroMem (&Packet, sizeof (Packet));
317
318 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
319 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
320 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
321
322 SdMmcCmdBlk.CommandIndex = EMMC_SEND_EXT_CSD;
323 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
324 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
325 SdMmcCmdBlk.CommandArgument = 0x00000000;
326
327 Packet.InDataBuffer = ExtCsd;
328 Packet.InTransferLength = sizeof (EMMC_EXT_CSD);
329
330 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
331 return Status;
332 }
333
334 /**
335 Send command SWITCH to the EMMC device to switch the mode of operation of the
336 selected Device or modifies the EXT_CSD registers.
337
338 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
339
340 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
341 @param[in] Slot The slot number of the SD card to send the command to.
342 @param[in] Access The access mode of SWTICH command.
343 @param[in] Index The offset of the field to be access.
344 @param[in] Value The value to be set to the specified field of EXT_CSD register.
345 @param[in] CmdSet The value of CmdSet field of EXT_CSD register.
346
347 @retval EFI_SUCCESS The operation is done correctly.
348 @retval Others The operation fails.
349
350 **/
351 EFI_STATUS
352 EmmcSwitch (
353 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
354 IN UINT8 Slot,
355 IN UINT8 Access,
356 IN UINT8 Index,
357 IN UINT8 Value,
358 IN UINT8 CmdSet
359 )
360 {
361 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
362 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
363 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
364 EFI_STATUS Status;
365
366 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
367 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
368 ZeroMem (&Packet, sizeof (Packet));
369
370 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
371 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
372 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
373
374 SdMmcCmdBlk.CommandIndex = EMMC_SWITCH;
375 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
376 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1b;
377 SdMmcCmdBlk.CommandArgument = (Access << 24) | (Index << 16) | (Value << 8) | CmdSet;
378
379 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
380
381 return Status;
382 }
383
384 /**
385 Send command SEND_STATUS to the addressed EMMC device to get its status register.
386
387 Refer to EMMC Electrical Standard Spec 5.1 Section 6.10.4 for details.
388
389 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
390 @param[in] Slot The slot number of the SD card to send the command to.
391 @param[in] Rca The relative device address of addressed device.
392 @param[out] DevStatus The returned device status.
393
394 @retval EFI_SUCCESS The operation is done correctly.
395 @retval Others The operation fails.
396
397 **/
398 EFI_STATUS
399 EmmcSendStatus (
400 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
401 IN UINT8 Slot,
402 IN UINT16 Rca,
403 OUT UINT32 *DevStatus
404 )
405 {
406 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
407 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
408 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
409 EFI_STATUS Status;
410
411 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
412 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
413 ZeroMem (&Packet, sizeof (Packet));
414
415 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
416 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
417 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
418
419 SdMmcCmdBlk.CommandIndex = EMMC_SEND_STATUS;
420 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAc;
421 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
422 SdMmcCmdBlk.CommandArgument = (UINT32)Rca << 16;
423
424 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
425 if (!EFI_ERROR (Status)) {
426 *DevStatus = SdMmcStatusBlk.Resp0;
427 }
428
429 return Status;
430 }
431
432 /**
433 Send command SEND_TUNING_BLOCK to the EMMC device for HS200 optimal sampling point
434 detection.
435
436 It may be sent up to 40 times until the host finishes the tuning procedure.
437
438 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 for details.
439
440 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
441 @param[in] Slot The slot number of the SD card to send the command to.
442 @param[in] BusWidth The bus width to work.
443
444 @retval EFI_SUCCESS The operation is done correctly.
445 @retval Others The operation fails.
446
447 **/
448 EFI_STATUS
449 EmmcSendTuningBlk (
450 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
451 IN UINT8 Slot,
452 IN UINT8 BusWidth
453 )
454 {
455 EFI_SD_MMC_COMMAND_BLOCK SdMmcCmdBlk;
456 EFI_SD_MMC_STATUS_BLOCK SdMmcStatusBlk;
457 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET Packet;
458 EFI_STATUS Status;
459 UINT8 TuningBlock[128];
460
461 ZeroMem (&SdMmcCmdBlk, sizeof (SdMmcCmdBlk));
462 ZeroMem (&SdMmcStatusBlk, sizeof (SdMmcStatusBlk));
463 ZeroMem (&Packet, sizeof (Packet));
464
465 Packet.SdMmcCmdBlk = &SdMmcCmdBlk;
466 Packet.SdMmcStatusBlk = &SdMmcStatusBlk;
467 Packet.Timeout = SD_MMC_HC_GENERIC_TIMEOUT;
468
469 SdMmcCmdBlk.CommandIndex = EMMC_SEND_TUNING_BLOCK;
470 SdMmcCmdBlk.CommandType = SdMmcCommandTypeAdtc;
471 SdMmcCmdBlk.ResponseType = SdMmcResponseTypeR1;
472 SdMmcCmdBlk.CommandArgument = 0;
473
474 Packet.InDataBuffer = TuningBlock;
475 if (BusWidth == 8) {
476 Packet.InTransferLength = sizeof (TuningBlock);
477 } else {
478 Packet.InTransferLength = 64;
479 }
480
481 Status = SdMmcPassThruPassThru (PassThru, Slot, &Packet, NULL);
482
483 return Status;
484 }
485
486 /**
487 Tunning the clock to get HS200 optimal sampling point.
488
489 Command SEND_TUNING_BLOCK may be sent up to 40 times until the host finishes the
490 tuning procedure.
491
492 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
493 Simplified Spec 3.0 Figure 2-29 for details.
494
495 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
496 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
497 @param[in] Slot The slot number of the SD card to send the command to.
498 @param[in] BusWidth The bus width to work.
499
500 @retval EFI_SUCCESS The operation is done correctly.
501 @retval Others The operation fails.
502
503 **/
504 EFI_STATUS
505 EmmcTuningClkForHs200 (
506 IN EFI_PCI_IO_PROTOCOL *PciIo,
507 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
508 IN UINT8 Slot,
509 IN UINT8 BusWidth
510 )
511 {
512 EFI_STATUS Status;
513 UINT8 HostCtrl2;
514 UINT8 Retry;
515
516 //
517 // Notify the host that the sampling clock tuning procedure starts.
518 //
519 HostCtrl2 = BIT6;
520 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
521 if (EFI_ERROR (Status)) {
522 return Status;
523 }
524
525 //
526 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
527 //
528 Retry = 0;
529 do {
530 Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
531 if (EFI_ERROR (Status)) {
532 DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
533 return Status;
534 }
535
536 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
537 if (EFI_ERROR (Status)) {
538 return Status;
539 }
540
541 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
542 break;
543 }
544
545 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
546 return EFI_SUCCESS;
547 }
548 } while (++Retry < 40);
549
550 DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
551 //
552 // Abort the tuning procedure and reset the tuning circuit.
553 //
554 HostCtrl2 = (UINT8) ~(BIT6 | BIT7);
555 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
556 if (EFI_ERROR (Status)) {
557 return Status;
558 }
559
560 return EFI_DEVICE_ERROR;
561 }
562
563 /**
564 Check the SWITCH operation status.
565
566 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
567 @param[in] Slot The slot number on which command should be sent.
568 @param[in] Rca The relative device address.
569
570 @retval EFI_SUCCESS The SWITCH finished siccessfully.
571 @retval others The SWITCH failed.
572 **/
573 EFI_STATUS
574 EmmcCheckSwitchStatus (
575 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
576 IN UINT8 Slot,
577 IN UINT16 Rca
578 )
579 {
580 EFI_STATUS Status;
581 UINT32 DevStatus;
582
583 Status = EmmcSendStatus (PassThru, Slot, Rca, &DevStatus);
584 if (EFI_ERROR (Status)) {
585 DEBUG ((DEBUG_ERROR, "EmmcCheckSwitchStatus: Send status fails with %r\n", Status));
586 return Status;
587 }
588
589 //
590 // Check the switch operation is really successful or not.
591 //
592 if ((DevStatus & BIT7) != 0) {
593 DEBUG ((DEBUG_ERROR, "EmmcCheckSwitchStatus: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
594 return EFI_DEVICE_ERROR;
595 }
596
597 return EFI_SUCCESS;
598 }
599
600 /**
601 Switch the bus width to specified width.
602
603 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
604 Simplified Spec 3.0 Figure 3-7 for details.
605
606 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
607 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
608 @param[in] Slot The slot number of the SD card to send the command to.
609 @param[in] Rca The relative device address to be assigned.
610 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
611 use single data rate data simpling method.
612 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
613
614 @retval EFI_SUCCESS The operation is done correctly.
615 @retval Others The operation fails.
616
617 **/
618 EFI_STATUS
619 EmmcSwitchBusWidth (
620 IN EFI_PCI_IO_PROTOCOL *PciIo,
621 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
622 IN UINT8 Slot,
623 IN UINT16 Rca,
624 IN BOOLEAN IsDdr,
625 IN UINT8 BusWidth
626 )
627 {
628 EFI_STATUS Status;
629 UINT8 Access;
630 UINT8 Index;
631 UINT8 Value;
632 UINT8 CmdSet;
633
634 //
635 // Write Byte, the Value field is written into the byte pointed by Index.
636 //
637 Access = 0x03;
638 Index = OFFSET_OF (EMMC_EXT_CSD, BusWidth);
639 if (BusWidth == 4) {
640 Value = 1;
641 } else if (BusWidth == 8) {
642 Value = 2;
643 } else {
644 return EFI_INVALID_PARAMETER;
645 }
646
647 if (IsDdr) {
648 Value += 4;
649 }
650
651 CmdSet = 0;
652 Status = EmmcSwitch (PassThru, Slot, Access, Index, Value, CmdSet);
653 if (EFI_ERROR (Status)) {
654 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
655 return Status;
656 }
657
658 Status = EmmcCheckSwitchStatus (PassThru, Slot, Rca);
659 if (EFI_ERROR (Status)) {
660 return Status;
661 }
662
663 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
664
665 return Status;
666 }
667
668 /**
669 Switch the bus timing and clock frequency.
670
671 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
672 Simplified Spec 3.0 Figure 3-3 for details.
673
674 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
675 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
676 @param[in] Slot The slot number of the SD card to send the command to.
677 @param[in] Rca The relative device address to be assigned.
678 @param[in] DriverStrength Driver strength to set for speed modes that support it.
679 @param[in] BusTiming The bus mode timing indicator.
680 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
681
682 @retval EFI_SUCCESS The operation is done correctly.
683 @retval Others The operation fails.
684
685 **/
686 EFI_STATUS
687 EmmcSwitchBusTiming (
688 IN EFI_PCI_IO_PROTOCOL *PciIo,
689 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
690 IN UINT8 Slot,
691 IN UINT16 Rca,
692 IN EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength,
693 IN SD_MMC_BUS_MODE BusTiming,
694 IN UINT32 ClockFreq
695 )
696 {
697 EFI_STATUS Status;
698 UINT8 Access;
699 UINT8 Index;
700 UINT8 Value;
701 UINT8 CmdSet;
702 SD_MMC_HC_PRIVATE_DATA *Private;
703 UINT8 HostCtrl1;
704 BOOLEAN DelaySendStatus;
705
706 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
707 //
708 // Write Byte, the Value field is written into the byte pointed by Index.
709 //
710 Access = 0x03;
711 Index = OFFSET_OF (EMMC_EXT_CSD, HsTiming);
712 CmdSet = 0;
713 switch (BusTiming) {
714 case SdMmcMmcHs400:
715 Value = (UINT8)((DriverStrength.Emmc << 4) | 3);
716 break;
717 case SdMmcMmcHs200:
718 Value = (UINT8)((DriverStrength.Emmc << 4) | 2);
719 break;
720 case SdMmcMmcHsSdr:
721 case SdMmcMmcHsDdr:
722 Value = 1;
723 break;
724 case SdMmcMmcLegacy:
725 Value = 0;
726 break;
727 default:
728 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: Unsupported BusTiming(%d)\n", BusTiming));
729 return EFI_INVALID_PARAMETER;
730 }
731
732 Status = EmmcSwitch (PassThru, Slot, Access, Index, Value, CmdSet);
733 if (EFI_ERROR (Status)) {
734 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: Switch to bus timing %d fails with %r\n", BusTiming, Status));
735 return Status;
736 }
737
738 if ((BusTiming == SdMmcMmcHsSdr) || (BusTiming == SdMmcMmcHsDdr)) {
739 HostCtrl1 = BIT2;
740 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
741 if (EFI_ERROR (Status)) {
742 return Status;
743 }
744 } else {
745 HostCtrl1 = (UINT8) ~BIT2;
746 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
747 if (EFI_ERROR (Status)) {
748 return Status;
749 }
750 }
751
752 Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusTiming);
753 if (EFI_ERROR (Status)) {
754 return Status;
755 }
756
757 //
758 // For cases when we switch bus timing to higher mode from current we want to
759 // send SEND_STATUS at current, lower, frequency then the target frequency to avoid
760 // stability issues. It has been observed that some designs are unable to process the
761 // SEND_STATUS at higher frequency during switch to HS200 @200MHz irrespective of the number of retries
762 // and only running the clock tuning is able to make them work at target frequency.
763 //
764 // For cases when we are downgrading the frequency and current high frequency is invalid
765 // we have to first change the frequency to target frequency and then send the SEND_STATUS.
766 //
767 if (Private->Slot[Slot].CurrentFreq < (ClockFreq * 1000)) {
768 Status = EmmcCheckSwitchStatus (PassThru, Slot, Rca);
769 if (EFI_ERROR (Status)) {
770 return Status;
771 }
772
773 DelaySendStatus = FALSE;
774 } else {
775 DelaySendStatus = TRUE;
776 }
777
778 //
779 // Convert the clock freq unit from MHz to KHz.
780 //
781 Status = SdMmcHcClockSupply (Private, Slot, BusTiming, FALSE, ClockFreq * 1000);
782 if (EFI_ERROR (Status)) {
783 return Status;
784 }
785
786 if (DelaySendStatus) {
787 Status = EmmcCheckSwitchStatus (PassThru, Slot, Rca);
788 if (EFI_ERROR (Status)) {
789 return Status;
790 }
791 }
792
793 return Status;
794 }
795
796 /**
797 Switch to the High Speed timing according to request.
798
799 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
800 Simplified Spec 3.0 Figure 2-29 for details.
801
802 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
803 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
804 @param[in] Slot The slot number of the SD card to send the command to.
805 @param[in] Rca The relative device address to be assigned.
806 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
807
808 @retval EFI_SUCCESS The operation is done correctly.
809 @retval Others The operation fails.
810
811 **/
812 EFI_STATUS
813 EmmcSwitchToHighSpeed (
814 IN EFI_PCI_IO_PROTOCOL *PciIo,
815 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
816 IN UINT8 Slot,
817 IN UINT16 Rca,
818 IN SD_MMC_BUS_SETTINGS *BusMode
819 )
820 {
821 EFI_STATUS Status;
822 BOOLEAN IsDdr;
823
824 if (((BusMode->BusTiming != SdMmcMmcHsSdr) && (BusMode->BusTiming != SdMmcMmcHsDdr) && (BusMode->BusTiming != SdMmcMmcLegacy)) ||
825 (BusMode->ClockFreq > 52))
826 {
827 return EFI_INVALID_PARAMETER;
828 }
829
830 if (BusMode->BusTiming == SdMmcMmcHsDdr) {
831 IsDdr = TRUE;
832 } else {
833 IsDdr = FALSE;
834 }
835
836 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusMode->BusWidth);
837 if (EFI_ERROR (Status)) {
838 return Status;
839 }
840
841 return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
842 }
843
844 /**
845 Switch to the HS200 timing. This function assumes that eMMC bus is still in legacy mode.
846
847 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
848 Simplified Spec 3.0 Figure 2-29 for details.
849
850 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
851 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
852 @param[in] Slot The slot number of the SD card to send the command to.
853 @param[in] Rca The relative device address to be assigned.
854 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
855
856 @retval EFI_SUCCESS The operation is done correctly.
857 @retval Others The operation fails.
858
859 **/
860 EFI_STATUS
861 EmmcSwitchToHS200 (
862 IN EFI_PCI_IO_PROTOCOL *PciIo,
863 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
864 IN UINT8 Slot,
865 IN UINT16 Rca,
866 IN SD_MMC_BUS_SETTINGS *BusMode
867 )
868 {
869 EFI_STATUS Status;
870
871 if ((BusMode->BusTiming != SdMmcMmcHs200) ||
872 ((BusMode->BusWidth != 4) && (BusMode->BusWidth != 8)))
873 {
874 return EFI_INVALID_PARAMETER;
875 }
876
877 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, FALSE, BusMode->BusWidth);
878 if (EFI_ERROR (Status)) {
879 return Status;
880 }
881
882 Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
883 if (EFI_ERROR (Status)) {
884 return Status;
885 }
886
887 Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusMode->BusWidth);
888
889 return Status;
890 }
891
892 /**
893 Switch to the HS400 timing. This function assumes that eMMC bus is still in legacy mode.
894
895 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
896 Simplified Spec 3.0 Figure 2-29 for details.
897
898 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
899 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
900 @param[in] Slot The slot number of the SD card to send the command to.
901 @param[in] Rca The relative device address to be assigned.
902 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
903
904 @retval EFI_SUCCESS The operation is done correctly.
905 @retval Others The operation fails.
906
907 **/
908 EFI_STATUS
909 EmmcSwitchToHS400 (
910 IN EFI_PCI_IO_PROTOCOL *PciIo,
911 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
912 IN UINT8 Slot,
913 IN UINT16 Rca,
914 IN SD_MMC_BUS_SETTINGS *BusMode
915 )
916 {
917 EFI_STATUS Status;
918 SD_MMC_BUS_SETTINGS Hs200BusMode;
919 UINT32 HsFreq;
920
921 if ((BusMode->BusTiming != SdMmcMmcHs400) ||
922 (BusMode->BusWidth != 8))
923 {
924 return EFI_INVALID_PARAMETER;
925 }
926
927 Hs200BusMode.BusTiming = SdMmcMmcHs200;
928 Hs200BusMode.BusWidth = BusMode->BusWidth;
929 Hs200BusMode.ClockFreq = BusMode->ClockFreq;
930 Hs200BusMode.DriverStrength = BusMode->DriverStrength;
931
932 Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, &Hs200BusMode);
933 if (EFI_ERROR (Status)) {
934 return Status;
935 }
936
937 //
938 // Set to High Speed timing and set the clock frequency to a value less than or equal to 52MHz.
939 // This step is necessary to be able to switch Bus into 8 bit DDR mode which is unsupported in HS200.
940 //
941 HsFreq = BusMode->ClockFreq < 52 ? BusMode->ClockFreq : 52;
942 Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, SdMmcMmcHsSdr, HsFreq);
943 if (EFI_ERROR (Status)) {
944 return Status;
945 }
946
947 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, TRUE, BusMode->BusWidth);
948 if (EFI_ERROR (Status)) {
949 return Status;
950 }
951
952 return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
953 }
954
955 /**
956 Check if passed BusTiming is supported in both controller and card.
957
958 @param[in] Private Pointer to controller private data
959 @param[in] SlotIndex Index of the slot in the controller
960 @param[in] ExtCsd Pointer to the card's extended CSD
961 @param[in] BusTiming Bus timing to check
962
963 @retval TRUE Both card and controller support given BusTiming
964 @retval FALSE Card or controller doesn't support given BusTiming
965 **/
966 BOOLEAN
967 EmmcIsBusTimingSupported (
968 IN SD_MMC_HC_PRIVATE_DATA *Private,
969 IN UINT8 SlotIndex,
970 IN EMMC_EXT_CSD *ExtCsd,
971 IN SD_MMC_BUS_MODE BusTiming
972 )
973 {
974 BOOLEAN Supported;
975 SD_MMC_HC_SLOT_CAP *Capabilities;
976
977 Capabilities = &Private->Capability[SlotIndex];
978
979 Supported = FALSE;
980 switch (BusTiming) {
981 case SdMmcMmcHs400:
982 if ((((ExtCsd->DeviceType & (BIT6 | BIT7)) != 0) && (Capabilities->Hs400 != 0)) && (Capabilities->BusWidth8 != 0)) {
983 Supported = TRUE;
984 }
985
986 break;
987 case SdMmcMmcHs200:
988 if ((((ExtCsd->DeviceType & (BIT4 | BIT5)) != 0) && (Capabilities->Sdr104 != 0))) {
989 Supported = TRUE;
990 }
991
992 break;
993 case SdMmcMmcHsDdr:
994 if ((((ExtCsd->DeviceType & (BIT2 | BIT3)) != 0) && (Capabilities->Ddr50 != 0))) {
995 Supported = TRUE;
996 }
997
998 break;
999 case SdMmcMmcHsSdr:
1000 if ((((ExtCsd->DeviceType & BIT1) != 0) && (Capabilities->HighSpeed != 0))) {
1001 Supported = TRUE;
1002 }
1003
1004 break;
1005 case SdMmcMmcLegacy:
1006 if ((ExtCsd->DeviceType & BIT0) != 0) {
1007 Supported = TRUE;
1008 }
1009
1010 break;
1011 default:
1012 ASSERT (FALSE);
1013 }
1014
1015 return Supported;
1016 }
1017
1018 /**
1019 Get the target bus timing to set on the link. This function
1020 will try to select highest bus timing supported by card, controller
1021 and the driver.
1022
1023 @param[in] Private Pointer to controller private data
1024 @param[in] SlotIndex Index of the slot in the controller
1025 @param[in] ExtCsd Pointer to the card's extended CSD
1026
1027 @return Bus timing value that should be set on link
1028 **/
1029 SD_MMC_BUS_MODE
1030 EmmcGetTargetBusTiming (
1031 IN SD_MMC_HC_PRIVATE_DATA *Private,
1032 IN UINT8 SlotIndex,
1033 IN EMMC_EXT_CSD *ExtCsd
1034 )
1035 {
1036 SD_MMC_BUS_MODE BusTiming;
1037
1038 //
1039 // We start with highest bus timing that this driver currently supports and
1040 // return as soon as we find supported timing.
1041 //
1042 BusTiming = SdMmcMmcHs400;
1043 while (BusTiming > SdMmcMmcLegacy) {
1044 if (EmmcIsBusTimingSupported (Private, SlotIndex, ExtCsd, BusTiming)) {
1045 break;
1046 }
1047
1048 BusTiming--;
1049 }
1050
1051 return BusTiming;
1052 }
1053
1054 /**
1055 Check if the passed bus width is supported by controller and card.
1056
1057 @param[in] Private Pointer to controller private data
1058 @param[in] SlotIndex Index of the slot in the controller
1059 @param[in] BusTiming Bus timing set on the link
1060 @param[in] BusWidth Bus width to check
1061
1062 @retval TRUE Passed bus width is supported in current bus configuration
1063 @retval FALSE Passed bus width is not supported in current bus configuration
1064 **/
1065 BOOLEAN
1066 EmmcIsBusWidthSupported (
1067 IN SD_MMC_HC_PRIVATE_DATA *Private,
1068 IN UINT8 SlotIndex,
1069 IN SD_MMC_BUS_MODE BusTiming,
1070 IN UINT16 BusWidth
1071 )
1072 {
1073 if ((BusWidth == 8) && (Private->Capability[SlotIndex].BusWidth8 != 0)) {
1074 return TRUE;
1075 } else if ((BusWidth == 4) && (BusTiming != SdMmcMmcHs400)) {
1076 return TRUE;
1077 } else if ((BusWidth == 1) && ((BusTiming == SdMmcMmcHsSdr) || (BusTiming == SdMmcMmcLegacy))) {
1078 return TRUE;
1079 }
1080
1081 return FALSE;
1082 }
1083
1084 /**
1085 Get the target bus width to be set on the bus.
1086
1087 @param[in] Private Pointer to controller private data
1088 @param[in] SlotIndex Index of the slot in the controller
1089 @param[in] ExtCsd Pointer to card's extended CSD
1090 @param[in] BusTiming Bus timing set on the bus
1091
1092 @return Bus width to be set on the bus
1093 **/
1094 UINT8
1095 EmmcGetTargetBusWidth (
1096 IN SD_MMC_HC_PRIVATE_DATA *Private,
1097 IN UINT8 SlotIndex,
1098 IN EMMC_EXT_CSD *ExtCsd,
1099 IN SD_MMC_BUS_MODE BusTiming
1100 )
1101 {
1102 UINT8 BusWidth;
1103 UINT8 PreferredBusWidth;
1104
1105 PreferredBusWidth = Private->Slot[SlotIndex].OperatingParameters.BusWidth;
1106
1107 if ((PreferredBusWidth != EDKII_SD_MMC_BUS_WIDTH_IGNORE) &&
1108 EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, PreferredBusWidth))
1109 {
1110 BusWidth = PreferredBusWidth;
1111 } else if (EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, 8)) {
1112 BusWidth = 8;
1113 } else if (EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, 4)) {
1114 BusWidth = 4;
1115 } else {
1116 BusWidth = 1;
1117 }
1118
1119 return BusWidth;
1120 }
1121
1122 /**
1123 Get the target clock frequency to be set on the bus.
1124
1125 @param[in] Private Pointer to controller private data
1126 @param[in] SlotIndex Index of the slot in the controller
1127 @param[in] ExtCsd Pointer to card's extended CSD
1128 @param[in] BusTiming Bus timing to be set on the bus
1129
1130 @return Value of the clock frequency to be set on bus in MHz
1131 **/
1132 UINT32
1133 EmmcGetTargetClockFreq (
1134 IN SD_MMC_HC_PRIVATE_DATA *Private,
1135 IN UINT8 SlotIndex,
1136 IN EMMC_EXT_CSD *ExtCsd,
1137 IN SD_MMC_BUS_MODE BusTiming
1138 )
1139 {
1140 UINT32 PreferredClockFreq;
1141 UINT32 MaxClockFreq;
1142
1143 PreferredClockFreq = Private->Slot[SlotIndex].OperatingParameters.ClockFreq;
1144
1145 switch (BusTiming) {
1146 case SdMmcMmcHs400:
1147 case SdMmcMmcHs200:
1148 MaxClockFreq = 200;
1149 break;
1150 case SdMmcMmcHsSdr:
1151 case SdMmcMmcHsDdr:
1152 MaxClockFreq = 52;
1153 break;
1154 default:
1155 MaxClockFreq = 26;
1156 break;
1157 }
1158
1159 if ((PreferredClockFreq != EDKII_SD_MMC_CLOCK_FREQ_IGNORE) && (PreferredClockFreq < MaxClockFreq)) {
1160 return PreferredClockFreq;
1161 } else {
1162 return MaxClockFreq;
1163 }
1164 }
1165
1166 /**
1167 Get the driver strength to be set on bus.
1168
1169 @param[in] Private Pointer to controller private data
1170 @param[in] SlotIndex Index of the slot in the controller
1171 @param[in] ExtCsd Pointer to card's extended CSD
1172 @param[in] BusTiming Bus timing set on the bus
1173
1174 @return Value of the driver strength to be set on the bus
1175 **/
1176 EDKII_SD_MMC_DRIVER_STRENGTH
1177 EmmcGetTargetDriverStrength (
1178 IN SD_MMC_HC_PRIVATE_DATA *Private,
1179 IN UINT8 SlotIndex,
1180 IN EMMC_EXT_CSD *ExtCsd,
1181 IN SD_MMC_BUS_MODE BusTiming
1182 )
1183 {
1184 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength;
1185 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength;
1186
1187 PreferredDriverStrength = Private->Slot[SlotIndex].OperatingParameters.DriverStrength;
1188 DriverStrength.Emmc = EmmcDriverStrengthType0;
1189
1190 if ((PreferredDriverStrength.Emmc != EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE) &&
1191 (ExtCsd->DriverStrength & (BIT0 << PreferredDriverStrength.Emmc)))
1192 {
1193 DriverStrength.Emmc = PreferredDriverStrength.Emmc;
1194 }
1195
1196 return DriverStrength;
1197 }
1198
1199 /**
1200 Get the target settings for the bus mode.
1201
1202 @param[in] Private Pointer to controller private data
1203 @param[in] SlotIndex Index of the slot in the controller
1204 @param[in] ExtCsd Pointer to card's extended CSD
1205 @param[out] BusMode Target configuration of the bus
1206 **/
1207 VOID
1208 EmmcGetTargetBusMode (
1209 IN SD_MMC_HC_PRIVATE_DATA *Private,
1210 IN UINT8 SlotIndex,
1211 IN EMMC_EXT_CSD *ExtCsd,
1212 OUT SD_MMC_BUS_SETTINGS *BusMode
1213 )
1214 {
1215 BusMode->BusTiming = EmmcGetTargetBusTiming (Private, SlotIndex, ExtCsd);
1216 BusMode->BusWidth = EmmcGetTargetBusWidth (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1217 BusMode->ClockFreq = EmmcGetTargetClockFreq (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1218 BusMode->DriverStrength = EmmcGetTargetDriverStrength (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1219 }
1220
1221 /**
1222 Switch the high speed timing according to request.
1223
1224 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
1225 Simplified Spec 3.0 Figure 2-29 for details.
1226
1227 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1228 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1229 @param[in] Slot The slot number of the SD card to send the command to.
1230 @param[in] Rca The relative device address to be assigned.
1231
1232 @retval EFI_SUCCESS The operation is done correctly.
1233 @retval Others The operation fails.
1234
1235 **/
1236 EFI_STATUS
1237 EmmcSetBusMode (
1238 IN EFI_PCI_IO_PROTOCOL *PciIo,
1239 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
1240 IN UINT8 Slot,
1241 IN UINT16 Rca
1242 )
1243 {
1244 EFI_STATUS Status;
1245 EMMC_CSD Csd;
1246 EMMC_EXT_CSD ExtCsd;
1247 SD_MMC_BUS_SETTINGS BusMode;
1248 SD_MMC_HC_PRIVATE_DATA *Private;
1249
1250 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
1251
1252 Status = EmmcGetCsd (PassThru, Slot, Rca, &Csd);
1253 if (EFI_ERROR (Status)) {
1254 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: GetCsd fails with %r\n", Status));
1255 return Status;
1256 }
1257
1258 Status = EmmcSelect (PassThru, Slot, Rca);
1259 if (EFI_ERROR (Status)) {
1260 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: Select fails with %r\n", Status));
1261 return Status;
1262 }
1263
1264 ASSERT (Private->BaseClkFreq[Slot] != 0);
1265
1266 //
1267 // Get Device_Type from EXT_CSD register.
1268 //
1269 Status = EmmcGetExtCsd (PassThru, Slot, &ExtCsd);
1270 if (EFI_ERROR (Status)) {
1271 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status));
1272 return Status;
1273 }
1274
1275 EmmcGetTargetBusMode (Private, Slot, &ExtCsd, &BusMode);
1276
1277 DEBUG ((
1278 DEBUG_INFO,
1279 "EmmcSetBusMode: Target bus mode: timing = %d, width = %d, clock freq = %d, driver strength = %d\n",
1280 BusMode.BusTiming,
1281 BusMode.BusWidth,
1282 BusMode.ClockFreq,
1283 BusMode.DriverStrength.Emmc
1284 ));
1285
1286 if (BusMode.BusTiming == SdMmcMmcHs400) {
1287 Status = EmmcSwitchToHS400 (PciIo, PassThru, Slot, Rca, &BusMode);
1288 } else if (BusMode.BusTiming == SdMmcMmcHs200) {
1289 Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, &BusMode);
1290 } else {
1291 //
1292 // Note that EmmcSwitchToHighSpeed is also called for SdMmcMmcLegacy
1293 // bus timing. This is because even though we might not want to
1294 // change the timing itself we still want to allow customization of
1295 // bus parameters such as clock frequency and bus width.
1296 //
1297 Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, &BusMode);
1298 }
1299
1300 DEBUG ((DEBUG_INFO, "EmmcSetBusMode: Switch to %a %r\n", (BusMode.BusTiming == SdMmcMmcHs400) ? "HS400" : ((BusMode.BusTiming == SdMmcMmcHs200) ? "HS200" : "HighSpeed"), Status));
1301
1302 return Status;
1303 }
1304
1305 /**
1306 Execute EMMC device identification procedure.
1307
1308 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1309
1310 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1311 @param[in] Slot The slot number of the SD card to send the command to.
1312
1313 @retval EFI_SUCCESS There is a EMMC card.
1314 @retval Others There is not a EMMC card.
1315
1316 **/
1317 EFI_STATUS
1318 EmmcIdentification (
1319 IN SD_MMC_HC_PRIVATE_DATA *Private,
1320 IN UINT8 Slot
1321 )
1322 {
1323 EFI_STATUS Status;
1324 EFI_PCI_IO_PROTOCOL *PciIo;
1325 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
1326 UINT32 Ocr;
1327 UINT16 Rca;
1328 UINTN Retry;
1329
1330 PciIo = Private->PciIo;
1331 PassThru = &Private->PassThru;
1332
1333 Status = EmmcReset (PassThru, Slot);
1334 if (EFI_ERROR (Status)) {
1335 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status));
1336 return Status;
1337 }
1338
1339 Ocr = 0;
1340 Retry = 0;
1341 do {
1342 Status = EmmcGetOcr (PassThru, Slot, &Ocr);
1343 if (EFI_ERROR (Status)) {
1344 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status));
1345 return Status;
1346 }
1347
1348 Ocr |= BIT30;
1349
1350 if (Retry++ == 100) {
1351 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1352 return EFI_DEVICE_ERROR;
1353 }
1354
1355 gBS->Stall (10 * 1000);
1356 } while ((Ocr & BIT31) == 0);
1357
1358 Status = EmmcGetAllCid (PassThru, Slot);
1359 if (EFI_ERROR (Status)) {
1360 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status));
1361 return Status;
1362 }
1363
1364 //
1365 // Slot starts from 0 and valid RCA starts from 1.
1366 // Here we takes a simple formula to calculate the RCA.
1367 // Don't support multiple devices on the slot, that is
1368 // shared bus slot feature.
1369 //
1370 Rca = Slot + 1;
1371 Status = EmmcSetRca (PassThru, Slot, Rca);
1372 if (EFI_ERROR (Status)) {
1373 DEBUG ((DEBUG_ERROR, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status));
1374 return Status;
1375 }
1376
1377 //
1378 // Enter Data Tranfer Mode.
1379 //
1380 DEBUG ((DEBUG_INFO, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot, Rca));
1381 Private->Slot[Slot].CardType = EmmcCardType;
1382
1383 Status = EmmcSetBusMode (PciIo, PassThru, Slot, Rca);
1384
1385 return Status;
1386 }