]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/EmmcDevice.c
MdeModulePkg/SdMmcPciHcDxe: Fix SdMmcMmcLegacy bus timing handling
[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 // Ask the device to send a sequence of tuning blocks till the tuning procedure is done.
526 //
527 Retry = 0;
528 do {
529 Status = EmmcSendTuningBlk (PassThru, Slot, BusWidth);
530 if (EFI_ERROR (Status)) {
531 DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails with %r\n", Status));
532 return Status;
533 }
534
535 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, TRUE, sizeof (HostCtrl2), &HostCtrl2);
536 if (EFI_ERROR (Status)) {
537 return Status;
538 }
539
540 if ((HostCtrl2 & (BIT6 | BIT7)) == 0) {
541 break;
542 }
543
544 if ((HostCtrl2 & (BIT6 | BIT7)) == BIT7) {
545 return EFI_SUCCESS;
546 }
547 } while (++Retry < 40);
548
549 DEBUG ((DEBUG_ERROR, "EmmcTuningClkForHs200: Send tuning block fails at %d times with HostCtrl2 %02x\n", Retry, HostCtrl2));
550 //
551 // Abort the tuning procedure and reset the tuning circuit.
552 //
553 HostCtrl2 = (UINT8)~(BIT6 | BIT7);
554 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);
555 if (EFI_ERROR (Status)) {
556 return Status;
557 }
558 return EFI_DEVICE_ERROR;
559 }
560
561 /**
562 Switch the bus width to specified width.
563
564 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.9 and SD Host Controller
565 Simplified Spec 3.0 Figure 3-7 for details.
566
567 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
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 to be assigned.
571 @param[in] IsDdr If TRUE, use dual data rate data simpling method. Otherwise
572 use single data rate data simpling method.
573 @param[in] BusWidth The bus width to be set, it could be 4 or 8.
574
575 @retval EFI_SUCCESS The operation is done correctly.
576 @retval Others The operation fails.
577
578 **/
579 EFI_STATUS
580 EmmcSwitchBusWidth (
581 IN EFI_PCI_IO_PROTOCOL *PciIo,
582 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
583 IN UINT8 Slot,
584 IN UINT16 Rca,
585 IN BOOLEAN IsDdr,
586 IN UINT8 BusWidth
587 )
588 {
589 EFI_STATUS Status;
590 UINT8 Access;
591 UINT8 Index;
592 UINT8 Value;
593 UINT8 CmdSet;
594 UINT32 DevStatus;
595
596 //
597 // Write Byte, the Value field is written into the byte pointed by Index.
598 //
599 Access = 0x03;
600 Index = OFFSET_OF (EMMC_EXT_CSD, BusWidth);
601 if (BusWidth == 4) {
602 Value = 1;
603 } else if (BusWidth == 8) {
604 Value = 2;
605 } else {
606 return EFI_INVALID_PARAMETER;
607 }
608
609 if (IsDdr) {
610 Value += 4;
611 }
612
613 CmdSet = 0;
614 Status = EmmcSwitch (PassThru, Slot, Access, Index, Value, CmdSet);
615 if (EFI_ERROR (Status)) {
616 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusWidth: Switch to bus width %d fails with %r\n", BusWidth, Status));
617 return Status;
618 }
619
620 Status = EmmcSendStatus (PassThru, Slot, Rca, &DevStatus);
621 if (EFI_ERROR (Status)) {
622 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusWidth: Send status fails with %r\n", Status));
623 return Status;
624 }
625 //
626 // Check the switch operation is really successful or not.
627 //
628 if ((DevStatus & BIT7) != 0) {
629 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusWidth: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
630 return EFI_DEVICE_ERROR;
631 }
632
633 Status = SdMmcHcSetBusWidth (PciIo, Slot, BusWidth);
634
635 return Status;
636 }
637
638 /**
639 Switch the bus timing and clock frequency.
640
641 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6 and SD Host Controller
642 Simplified Spec 3.0 Figure 3-3 for details.
643
644 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
645 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
646 @param[in] Slot The slot number of the SD card to send the command to.
647 @param[in] Rca The relative device address to be assigned.
648 @param[in] DriverStrength Driver strength to set for speed modes that support it.
649 @param[in] BusTiming The bus mode timing indicator.
650 @param[in] ClockFreq The max clock frequency to be set, the unit is MHz.
651
652 @retval EFI_SUCCESS The operation is done correctly.
653 @retval Others The operation fails.
654
655 **/
656 EFI_STATUS
657 EmmcSwitchBusTiming (
658 IN EFI_PCI_IO_PROTOCOL *PciIo,
659 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
660 IN UINT8 Slot,
661 IN UINT16 Rca,
662 IN EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength,
663 IN SD_MMC_BUS_MODE BusTiming,
664 IN UINT32 ClockFreq
665 )
666 {
667 EFI_STATUS Status;
668 UINT8 Access;
669 UINT8 Index;
670 UINT8 Value;
671 UINT8 CmdSet;
672 UINT32 DevStatus;
673 SD_MMC_HC_PRIVATE_DATA *Private;
674 UINT8 HostCtrl1;
675
676 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
677 //
678 // Write Byte, the Value field is written into the byte pointed by Index.
679 //
680 Access = 0x03;
681 Index = OFFSET_OF (EMMC_EXT_CSD, HsTiming);
682 CmdSet = 0;
683 switch (BusTiming) {
684 case SdMmcMmcHs400:
685 Value = (UINT8)((DriverStrength.Emmc << 4) | 3);
686 break;
687 case SdMmcMmcHs200:
688 Value = (UINT8)((DriverStrength.Emmc << 4) | 2);
689 break;
690 case SdMmcMmcHsSdr:
691 case SdMmcMmcHsDdr:
692 Value = 1;
693 break;
694 case SdMmcMmcLegacy:
695 Value = 0;
696 break;
697 default:
698 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: Unsupported BusTiming(%d\n)", BusTiming));
699 return EFI_INVALID_PARAMETER;
700 }
701
702 Status = EmmcSwitch (PassThru, Slot, Access, Index, Value, CmdSet);
703 if (EFI_ERROR (Status)) {
704 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: Switch to bus timing %d fails with %r\n", BusTiming, Status));
705 return Status;
706 }
707
708 if (BusTiming == SdMmcMmcHsSdr || BusTiming == SdMmcMmcHsDdr) {
709 HostCtrl1 = BIT2;
710 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
711 if (EFI_ERROR (Status)) {
712 return Status;
713 }
714 } else {
715 HostCtrl1 = (UINT8)~BIT2;
716 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);
717 if (EFI_ERROR (Status)) {
718 return Status;
719 }
720 }
721
722 Status = SdMmcHcUhsSignaling (Private->ControllerHandle, PciIo, Slot, BusTiming);
723 if (EFI_ERROR (Status)) {
724 return Status;
725 }
726
727 //
728 // Convert the clock freq unit from MHz to KHz.
729 //
730 Status = SdMmcHcClockSupply (PciIo, Slot, ClockFreq * 1000, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);
731 if (EFI_ERROR (Status)) {
732 return Status;
733 }
734
735 Status = EmmcSendStatus (PassThru, Slot, Rca, &DevStatus);
736 if (EFI_ERROR (Status)) {
737 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: Send status fails with %r\n", Status));
738 return Status;
739 }
740 //
741 // Check the switch operation is really successful or not.
742 //
743 if ((DevStatus & BIT7) != 0) {
744 DEBUG ((DEBUG_ERROR, "EmmcSwitchBusTiming: The switch operation fails as DevStatus is 0x%08x\n", DevStatus));
745 return EFI_DEVICE_ERROR;
746 }
747
748 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {
749 Status = mOverride->NotifyPhase (
750 Private->ControllerHandle,
751 Slot,
752 EdkiiSdMmcSwitchClockFreqPost,
753 &BusTiming
754 );
755 if (EFI_ERROR (Status)) {
756 DEBUG ((
757 DEBUG_ERROR,
758 "%a: SD/MMC switch clock freq post notifier callback failed - %r\n",
759 __FUNCTION__,
760 Status
761 ));
762 return Status;
763 }
764 }
765
766 return Status;
767 }
768
769 /**
770 Switch to the High Speed timing according to request.
771
772 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
773 Simplified Spec 3.0 Figure 2-29 for details.
774
775 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
776 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
777 @param[in] Slot The slot number of the SD card to send the command to.
778 @param[in] Rca The relative device address to be assigned.
779 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
780
781 @retval EFI_SUCCESS The operation is done correctly.
782 @retval Others The operation fails.
783
784 **/
785 EFI_STATUS
786 EmmcSwitchToHighSpeed (
787 IN EFI_PCI_IO_PROTOCOL *PciIo,
788 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
789 IN UINT8 Slot,
790 IN UINT16 Rca,
791 IN SD_MMC_BUS_SETTINGS *BusMode
792 )
793 {
794 EFI_STATUS Status;
795 BOOLEAN IsDdr;
796
797 if ((BusMode->BusTiming != SdMmcMmcHsSdr && BusMode->BusTiming != SdMmcMmcHsDdr && BusMode->BusTiming != SdMmcMmcLegacy) ||
798 BusMode->ClockFreq > 52) {
799 return EFI_INVALID_PARAMETER;
800 }
801
802 if (BusMode->BusTiming == SdMmcMmcHsDdr) {
803 IsDdr = TRUE;
804 } else {
805 IsDdr = FALSE;
806 }
807
808 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, IsDdr, BusMode->BusWidth);
809 if (EFI_ERROR (Status)) {
810 return Status;
811 }
812
813 return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
814 }
815
816 /**
817 Switch to the HS200 timing. This function assumes that eMMC bus is still in legacy mode.
818
819 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
820 Simplified Spec 3.0 Figure 2-29 for details.
821
822 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
823 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
824 @param[in] Slot The slot number of the SD card to send the command to.
825 @param[in] Rca The relative device address to be assigned.
826 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
827
828 @retval EFI_SUCCESS The operation is done correctly.
829 @retval Others The operation fails.
830
831 **/
832 EFI_STATUS
833 EmmcSwitchToHS200 (
834 IN EFI_PCI_IO_PROTOCOL *PciIo,
835 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
836 IN UINT8 Slot,
837 IN UINT16 Rca,
838 IN SD_MMC_BUS_SETTINGS *BusMode
839 )
840 {
841 EFI_STATUS Status;
842
843 if (BusMode->BusTiming != SdMmcMmcHs200 ||
844 (BusMode->BusWidth != 4 && BusMode->BusWidth != 8)) {
845 return EFI_INVALID_PARAMETER;
846 }
847
848 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, FALSE, BusMode->BusWidth);
849 if (EFI_ERROR (Status)) {
850 return Status;
851 }
852
853 Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
854 if (EFI_ERROR (Status)) {
855 return Status;
856 }
857
858 Status = EmmcTuningClkForHs200 (PciIo, PassThru, Slot, BusMode->BusWidth);
859
860 return Status;
861 }
862
863 /**
864 Switch to the HS400 timing. This function assumes that eMMC bus is still in legacy mode.
865
866 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
867 Simplified Spec 3.0 Figure 2-29 for details.
868
869 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
870 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
871 @param[in] Slot The slot number of the SD card to send the command to.
872 @param[in] Rca The relative device address to be assigned.
873 @param[in] BusMode Pointer to SD_MMC_BUS_SETTINGS structure containing bus settings.
874
875 @retval EFI_SUCCESS The operation is done correctly.
876 @retval Others The operation fails.
877
878 **/
879 EFI_STATUS
880 EmmcSwitchToHS400 (
881 IN EFI_PCI_IO_PROTOCOL *PciIo,
882 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
883 IN UINT8 Slot,
884 IN UINT16 Rca,
885 IN SD_MMC_BUS_SETTINGS *BusMode
886 )
887 {
888 EFI_STATUS Status;
889 SD_MMC_BUS_SETTINGS Hs200BusMode;
890 UINT32 HsFreq;
891
892 if (BusMode->BusTiming != SdMmcMmcHs400 ||
893 BusMode->BusWidth != 8) {
894 return EFI_INVALID_PARAMETER;
895 }
896
897 Hs200BusMode.BusTiming = SdMmcMmcHs200;
898 Hs200BusMode.BusWidth = BusMode->BusWidth;
899 Hs200BusMode.ClockFreq = BusMode->ClockFreq;
900 Hs200BusMode.DriverStrength = BusMode->DriverStrength;
901
902 Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, &Hs200BusMode);
903 if (EFI_ERROR (Status)) {
904 return Status;
905 }
906
907 //
908 // Set to High Speed timing and set the clock frequency to a value less than or equal to 52MHz.
909 // This step is necessary to be able to switch Bus into 8 bit DDR mode which is unsupported in HS200.
910 //
911 HsFreq = BusMode->ClockFreq < 52 ? BusMode->ClockFreq : 52;
912 Status = EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, SdMmcMmcHsSdr, HsFreq);
913 if (EFI_ERROR (Status)) {
914 return Status;
915 }
916
917 Status = EmmcSwitchBusWidth (PciIo, PassThru, Slot, Rca, TRUE, BusMode->BusWidth);
918 if (EFI_ERROR (Status)) {
919 return Status;
920 }
921
922 return EmmcSwitchBusTiming (PciIo, PassThru, Slot, Rca, BusMode->DriverStrength, BusMode->BusTiming, BusMode->ClockFreq);
923 }
924
925 /**
926 Check if passed BusTiming is supported in both controller and card.
927
928 @param[in] Private Pointer to controller private data
929 @param[in] SlotIndex Index of the slot in the controller
930 @param[in] ExtCsd Pointer to the card's extended CSD
931 @param[in] BusTiming Bus timing to check
932
933 @retval TRUE Both card and controller support given BusTiming
934 @retval FALSE Card or controller doesn't support given BusTiming
935 **/
936 BOOLEAN
937 EmmcIsBusTimingSupported (
938 IN SD_MMC_HC_PRIVATE_DATA *Private,
939 IN UINT8 SlotIndex,
940 IN EMMC_EXT_CSD *ExtCsd,
941 IN SD_MMC_BUS_MODE BusTiming
942 )
943 {
944 BOOLEAN Supported;
945 SD_MMC_HC_SLOT_CAP *Capabilities;
946
947 Capabilities = &Private->Capability[SlotIndex];
948
949 Supported = FALSE;
950 switch (BusTiming) {
951 case SdMmcMmcHs400:
952 if ((((ExtCsd->DeviceType & (BIT6 | BIT7)) != 0) && (Capabilities->Hs400 != 0)) && Capabilities->BusWidth8 != 0) {
953 Supported = TRUE;
954 }
955 break;
956 case SdMmcMmcHs200:
957 if ((((ExtCsd->DeviceType & (BIT4 | BIT5)) != 0) && (Capabilities->Sdr104 != 0))) {
958 Supported = TRUE;
959 }
960 break;
961 case SdMmcMmcHsDdr:
962 if ((((ExtCsd->DeviceType & (BIT2 | BIT3)) != 0) && (Capabilities->Ddr50 != 0))) {
963 Supported = TRUE;
964 }
965 break;
966 case SdMmcMmcHsSdr:
967 if ((((ExtCsd->DeviceType & BIT1) != 0) && (Capabilities->HighSpeed != 0))) {
968 Supported = TRUE;
969 }
970 break;
971 case SdMmcMmcLegacy:
972 if ((ExtCsd->DeviceType & BIT0) != 0) {
973 Supported = TRUE;
974 }
975 break;
976 default:
977 ASSERT (FALSE);
978 }
979
980 return Supported;
981 }
982
983 /**
984 Get the target bus timing to set on the link. This function
985 will try to select highest bus timing supported by card, controller
986 and the driver.
987
988 @param[in] Private Pointer to controller private data
989 @param[in] SlotIndex Index of the slot in the controller
990 @param[in] ExtCsd Pointer to the card's extended CSD
991
992 @return Bus timing value that should be set on link
993 **/
994 SD_MMC_BUS_MODE
995 EmmcGetTargetBusTiming (
996 IN SD_MMC_HC_PRIVATE_DATA *Private,
997 IN UINT8 SlotIndex,
998 IN EMMC_EXT_CSD *ExtCsd
999 )
1000 {
1001 SD_MMC_BUS_MODE BusTiming;
1002
1003 //
1004 // We start with highest bus timing that this driver currently supports and
1005 // return as soon as we find supported timing.
1006 //
1007 BusTiming = SdMmcMmcHs400;
1008 while (BusTiming > SdMmcMmcLegacy) {
1009 if (EmmcIsBusTimingSupported (Private, SlotIndex, ExtCsd, BusTiming)) {
1010 break;
1011 }
1012 BusTiming--;
1013 }
1014
1015 return BusTiming;
1016 }
1017
1018 /**
1019 Check if the passed bus width is supported by controller and card.
1020
1021 @param[in] Private Pointer to controller private data
1022 @param[in] SlotIndex Index of the slot in the controller
1023 @param[in] BusTiming Bus timing set on the link
1024 @param[in] BusWidth Bus width to check
1025
1026 @retval TRUE Passed bus width is supported in current bus configuration
1027 @retval FALSE Passed bus width is not supported in current bus configuration
1028 **/
1029 BOOLEAN
1030 EmmcIsBusWidthSupported (
1031 IN SD_MMC_HC_PRIVATE_DATA *Private,
1032 IN UINT8 SlotIndex,
1033 IN SD_MMC_BUS_MODE BusTiming,
1034 IN UINT16 BusWidth
1035 )
1036 {
1037 if (BusWidth == 8 && Private->Capability[SlotIndex].BusWidth8 != 0) {
1038 return TRUE;
1039 } else if (BusWidth == 4 && BusTiming != SdMmcMmcHs400) {
1040 return TRUE;
1041 } else if (BusWidth == 1 && (BusTiming == SdMmcMmcHsSdr || BusTiming == SdMmcMmcLegacy)) {
1042 return TRUE;
1043 }
1044
1045 return FALSE;
1046 }
1047
1048 /**
1049 Get the target bus width to be set on the bus.
1050
1051 @param[in] Private Pointer to controller private data
1052 @param[in] SlotIndex Index of the slot in the controller
1053 @param[in] ExtCsd Pointer to card's extended CSD
1054 @param[in] BusTiming Bus timing set on the bus
1055
1056 @return Bus width to be set on the bus
1057 **/
1058 UINT8
1059 EmmcGetTargetBusWidth (
1060 IN SD_MMC_HC_PRIVATE_DATA *Private,
1061 IN UINT8 SlotIndex,
1062 IN EMMC_EXT_CSD *ExtCsd,
1063 IN SD_MMC_BUS_MODE BusTiming
1064 )
1065 {
1066 UINT8 BusWidth;
1067 UINT8 PreferredBusWidth;
1068
1069 PreferredBusWidth = Private->Slot[SlotIndex].OperatingParameters.BusWidth;
1070
1071 if (PreferredBusWidth != EDKII_SD_MMC_BUS_WIDTH_IGNORE &&
1072 EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, PreferredBusWidth)) {
1073 BusWidth = PreferredBusWidth;
1074 } else if (EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, 8)) {
1075 BusWidth = 8;
1076 } else if (EmmcIsBusWidthSupported (Private, SlotIndex, BusTiming, 4)) {
1077 BusWidth = 4;
1078 } else {
1079 BusWidth = 1;
1080 }
1081
1082 return BusWidth;
1083 }
1084
1085 /**
1086 Get the target clock frequency to be set on the bus.
1087
1088 @param[in] Private Pointer to controller private data
1089 @param[in] SlotIndex Index of the slot in the controller
1090 @param[in] ExtCsd Pointer to card's extended CSD
1091 @param[in] BusTiming Bus timing to be set on the bus
1092
1093 @return Value of the clock frequency to be set on bus in MHz
1094 **/
1095 UINT32
1096 EmmcGetTargetClockFreq (
1097 IN SD_MMC_HC_PRIVATE_DATA *Private,
1098 IN UINT8 SlotIndex,
1099 IN EMMC_EXT_CSD *ExtCsd,
1100 IN SD_MMC_BUS_MODE BusTiming
1101 )
1102 {
1103 UINT32 PreferredClockFreq;
1104 UINT32 MaxClockFreq;
1105
1106 PreferredClockFreq = Private->Slot[SlotIndex].OperatingParameters.ClockFreq;
1107
1108 switch (BusTiming) {
1109 case SdMmcMmcHs400:
1110 case SdMmcMmcHs200:
1111 MaxClockFreq = 200;
1112 break;
1113 case SdMmcMmcHsSdr:
1114 case SdMmcMmcHsDdr:
1115 MaxClockFreq = 52;
1116 break;
1117 default:
1118 MaxClockFreq = 26;
1119 break;
1120 }
1121
1122 if (PreferredClockFreq != EDKII_SD_MMC_CLOCK_FREQ_IGNORE && PreferredClockFreq < MaxClockFreq) {
1123 return PreferredClockFreq;
1124 } else {
1125 return MaxClockFreq;
1126 }
1127 }
1128
1129 /**
1130 Get the driver strength to be set on bus.
1131
1132 @param[in] Private Pointer to controller private data
1133 @param[in] SlotIndex Index of the slot in the controller
1134 @param[in] ExtCsd Pointer to card's extended CSD
1135 @param[in] BusTiming Bus timing set on the bus
1136
1137 @return Value of the driver strength to be set on the bus
1138 **/
1139 EDKII_SD_MMC_DRIVER_STRENGTH
1140 EmmcGetTargetDriverStrength (
1141 IN SD_MMC_HC_PRIVATE_DATA *Private,
1142 IN UINT8 SlotIndex,
1143 IN EMMC_EXT_CSD *ExtCsd,
1144 IN SD_MMC_BUS_MODE BusTiming
1145 )
1146 {
1147 EDKII_SD_MMC_DRIVER_STRENGTH PreferredDriverStrength;
1148 EDKII_SD_MMC_DRIVER_STRENGTH DriverStrength;
1149
1150 PreferredDriverStrength = Private->Slot[SlotIndex].OperatingParameters.DriverStrength;
1151 DriverStrength.Emmc = EmmcDriverStrengthType0;
1152
1153 if (PreferredDriverStrength.Emmc != EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE &&
1154 (ExtCsd->DriverStrength & (BIT0 << PreferredDriverStrength.Emmc))) {
1155 DriverStrength.Emmc = PreferredDriverStrength.Emmc;
1156 }
1157
1158 return DriverStrength;
1159 }
1160
1161 /**
1162 Get the target settings for the bus mode.
1163
1164 @param[in] Private Pointer to controller private data
1165 @param[in] SlotIndex Index of the slot in the controller
1166 @param[in] ExtCsd Pointer to card's extended CSD
1167 @param[out] BusMode Target configuration of the bus
1168 **/
1169 VOID
1170 EmmcGetTargetBusMode (
1171 IN SD_MMC_HC_PRIVATE_DATA *Private,
1172 IN UINT8 SlotIndex,
1173 IN EMMC_EXT_CSD *ExtCsd,
1174 OUT SD_MMC_BUS_SETTINGS *BusMode
1175 )
1176 {
1177 BusMode->BusTiming = EmmcGetTargetBusTiming (Private, SlotIndex, ExtCsd);
1178 BusMode->BusWidth = EmmcGetTargetBusWidth (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1179 BusMode->ClockFreq = EmmcGetTargetClockFreq (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1180 BusMode->DriverStrength = EmmcGetTargetDriverStrength (Private, SlotIndex, ExtCsd, BusMode->BusTiming);
1181 }
1182
1183 /**
1184 Switch the high speed timing according to request.
1185
1186 Refer to EMMC Electrical Standard Spec 5.1 Section 6.6.8 and SD Host Controller
1187 Simplified Spec 3.0 Figure 2-29 for details.
1188
1189 @param[in] PciIo A pointer to the EFI_PCI_IO_PROTOCOL instance.
1190 @param[in] PassThru A pointer to the EFI_SD_MMC_PASS_THRU_PROTOCOL instance.
1191 @param[in] Slot The slot number of the SD card to send the command to.
1192 @param[in] Rca The relative device address to be assigned.
1193
1194 @retval EFI_SUCCESS The operation is done correctly.
1195 @retval Others The operation fails.
1196
1197 **/
1198 EFI_STATUS
1199 EmmcSetBusMode (
1200 IN EFI_PCI_IO_PROTOCOL *PciIo,
1201 IN EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru,
1202 IN UINT8 Slot,
1203 IN UINT16 Rca
1204 )
1205 {
1206 EFI_STATUS Status;
1207 EMMC_CSD Csd;
1208 EMMC_EXT_CSD ExtCsd;
1209 SD_MMC_BUS_SETTINGS BusMode;
1210 SD_MMC_HC_PRIVATE_DATA *Private;
1211
1212 Private = SD_MMC_HC_PRIVATE_FROM_THIS (PassThru);
1213
1214 Status = EmmcGetCsd (PassThru, Slot, Rca, &Csd);
1215 if (EFI_ERROR (Status)) {
1216 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: GetCsd fails with %r\n", Status));
1217 return Status;
1218 }
1219
1220 Status = EmmcSelect (PassThru, Slot, Rca);
1221 if (EFI_ERROR (Status)) {
1222 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: Select fails with %r\n", Status));
1223 return Status;
1224 }
1225
1226 ASSERT (Private->BaseClkFreq[Slot] != 0);
1227
1228 //
1229 // Get Device_Type from EXT_CSD register.
1230 //
1231 Status = EmmcGetExtCsd (PassThru, Slot, &ExtCsd);
1232 if (EFI_ERROR (Status)) {
1233 DEBUG ((DEBUG_ERROR, "EmmcSetBusMode: GetExtCsd fails with %r\n", Status));
1234 return Status;
1235 }
1236
1237 EmmcGetTargetBusMode (Private, Slot, &ExtCsd, &BusMode);
1238
1239 DEBUG ((DEBUG_INFO, "EmmcSetBusMode: Target bus mode: timing = %d, width = %d, clock freq = %d, driver strength = %d\n",
1240 BusMode.BusTiming, BusMode.BusWidth, BusMode.ClockFreq, BusMode.DriverStrength.Emmc));
1241
1242 if (BusMode.BusTiming == SdMmcMmcHs400) {
1243 Status = EmmcSwitchToHS400 (PciIo, PassThru, Slot, Rca, &BusMode);
1244 } else if (BusMode.BusTiming == SdMmcMmcHs200) {
1245 Status = EmmcSwitchToHS200 (PciIo, PassThru, Slot, Rca, &BusMode);
1246 } else {
1247 //
1248 // Note that EmmcSwitchToHighSpeed is also called for SdMmcMmcLegacy
1249 // bus timing. This is because even though we might not want to
1250 // change the timing itself we still want to allow customization of
1251 // bus parameters such as clock frequency and bus width.
1252 //
1253 Status = EmmcSwitchToHighSpeed (PciIo, PassThru, Slot, Rca, &BusMode);
1254 }
1255
1256 DEBUG ((DEBUG_INFO, "EmmcSetBusMode: Switch to %a %r\n", (BusMode.BusTiming == SdMmcMmcHs400) ? "HS400" : ((BusMode.BusTiming == SdMmcMmcHs200) ? "HS200" : "HighSpeed"), Status));
1257
1258 return Status;
1259 }
1260
1261 /**
1262 Execute EMMC device identification procedure.
1263
1264 Refer to EMMC Electrical Standard Spec 5.1 Section 6.4 for details.
1265
1266 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.
1267 @param[in] Slot The slot number of the SD card to send the command to.
1268
1269 @retval EFI_SUCCESS There is a EMMC card.
1270 @retval Others There is not a EMMC card.
1271
1272 **/
1273 EFI_STATUS
1274 EmmcIdentification (
1275 IN SD_MMC_HC_PRIVATE_DATA *Private,
1276 IN UINT8 Slot
1277 )
1278 {
1279 EFI_STATUS Status;
1280 EFI_PCI_IO_PROTOCOL *PciIo;
1281 EFI_SD_MMC_PASS_THRU_PROTOCOL *PassThru;
1282 UINT32 Ocr;
1283 UINT16 Rca;
1284 UINTN Retry;
1285
1286 PciIo = Private->PciIo;
1287 PassThru = &Private->PassThru;
1288
1289 Status = EmmcReset (PassThru, Slot);
1290 if (EFI_ERROR (Status)) {
1291 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd0 fails with %r\n", Status));
1292 return Status;
1293 }
1294
1295 Ocr = 0;
1296 Retry = 0;
1297 do {
1298 Status = EmmcGetOcr (PassThru, Slot, &Ocr);
1299 if (EFI_ERROR (Status)) {
1300 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd1 fails with %r\n", Status));
1301 return Status;
1302 }
1303 Ocr |= BIT30;
1304
1305 if (Retry++ == 100) {
1306 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd1 fails too many times\n"));
1307 return EFI_DEVICE_ERROR;
1308 }
1309 gBS->Stall(10 * 1000);
1310 } while ((Ocr & BIT31) == 0);
1311
1312 Status = EmmcGetAllCid (PassThru, Slot);
1313 if (EFI_ERROR (Status)) {
1314 DEBUG ((DEBUG_VERBOSE, "EmmcIdentification: Executing Cmd2 fails with %r\n", Status));
1315 return Status;
1316 }
1317 //
1318 // Slot starts from 0 and valid RCA starts from 1.
1319 // Here we takes a simple formula to calculate the RCA.
1320 // Don't support multiple devices on the slot, that is
1321 // shared bus slot feature.
1322 //
1323 Rca = Slot + 1;
1324 Status = EmmcSetRca (PassThru, Slot, Rca);
1325 if (EFI_ERROR (Status)) {
1326 DEBUG ((DEBUG_ERROR, "EmmcIdentification: Executing Cmd3 fails with %r\n", Status));
1327 return Status;
1328 }
1329 //
1330 // Enter Data Tranfer Mode.
1331 //
1332 DEBUG ((DEBUG_INFO, "EmmcIdentification: Found a EMMC device at slot [%d], RCA [%d]\n", Slot, Rca));
1333 Private->Slot[Slot].CardType = EmmcCardType;
1334
1335 Status = EmmcSetBusMode (PciIo, PassThru, Slot, Rca);
1336
1337 return Status;
1338 }
1339