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