]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c
EmbeddedPkg: Apply uncrustify changes
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / MmcIdentification.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-2-Clause-Patent
6 *
7 **/
8
9 #include <Library/BaseMemoryLib.h>
10 #include <Library/MemoryAllocationLib.h>
11 #include <Library/TimerLib.h>
12
13 #include "Mmc.h"
14
15 typedef union {
16 UINT32 Raw;
17 OCR Ocr;
18 } OCR_RESPONSE;
19
20 #define MAX_RETRY_COUNT 1000
21 #define CMD_RETRY_COUNT 20
22 #define RCA_SHIFT_OFFSET 16
23 #define EMMC_CARD_SIZE 512
24 #define EMMC_ECSD_SIZE_OFFSET 53
25
26 #define EXTCSD_BUS_WIDTH 183
27 #define EXTCSD_HS_TIMING 185
28
29 #define EMMC_TIMING_BACKWARD 0
30 #define EMMC_TIMING_HS 1
31 #define EMMC_TIMING_HS200 2
32 #define EMMC_TIMING_HS400 3
33
34 #define EMMC_BUS_WIDTH_1BIT 0
35 #define EMMC_BUS_WIDTH_4BIT 1
36 #define EMMC_BUS_WIDTH_8BIT 2
37 #define EMMC_BUS_WIDTH_DDR_4BIT 5
38 #define EMMC_BUS_WIDTH_DDR_8BIT 6
39
40 #define EMMC_SWITCH_ERROR (1 << 7)
41
42 #define SD_BUS_WIDTH_1BIT (1 << 0)
43 #define SD_BUS_WIDTH_4BIT (1 << 2)
44
45 #define SD_CCC_SWITCH (1 << 10)
46
47 #define DEVICE_STATE(x) (((x) >> 9) & 0xf)
48 typedef enum _EMMC_DEVICE_STATE {
49 EMMC_IDLE_STATE = 0,
50 EMMC_READY_STATE,
51 EMMC_IDENT_STATE,
52 EMMC_STBY_STATE,
53 EMMC_TRAN_STATE,
54 EMMC_DATA_STATE,
55 EMMC_RCV_STATE,
56 EMMC_PRG_STATE,
57 EMMC_DIS_STATE,
58 EMMC_BTST_STATE,
59 EMMC_SLP_STATE
60 } EMMC_DEVICE_STATE;
61
62 UINT32 mEmmcRcaCount = 0;
63
64 STATIC
65 EFI_STATUS
66 EFIAPI
67 EmmcGetDeviceState (
68 IN MMC_HOST_INSTANCE *MmcHostInstance,
69 OUT EMMC_DEVICE_STATE *State
70 )
71 {
72 EFI_MMC_HOST_PROTOCOL *Host;
73 EFI_STATUS Status;
74 UINT32 Data, RCA;
75
76 if (State == NULL) {
77 return EFI_INVALID_PARAMETER;
78 }
79
80 Host = MmcHostInstance->MmcHost;
81 RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
82 Status = Host->SendCommand (Host, MMC_CMD13, RCA);
83 if (EFI_ERROR (Status)) {
84 DEBUG ((DEBUG_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status));
85 return Status;
86 }
87
88 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, &Data);
89 if (EFI_ERROR (Status)) {
90 DEBUG ((DEBUG_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status));
91 return Status;
92 }
93
94 if (Data & EMMC_SWITCH_ERROR) {
95 DEBUG ((DEBUG_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status));
96 return EFI_DEVICE_ERROR;
97 }
98
99 *State = DEVICE_STATE (Data);
100 return EFI_SUCCESS;
101 }
102
103 STATIC
104 EFI_STATUS
105 EFIAPI
106 EmmcSetEXTCSD (
107 IN MMC_HOST_INSTANCE *MmcHostInstance,
108 UINT32 ExtCmdIndex,
109 UINT32 Value
110 )
111 {
112 EFI_MMC_HOST_PROTOCOL *Host;
113 EMMC_DEVICE_STATE State;
114 EFI_STATUS Status;
115 UINT32 Argument;
116
117 Host = MmcHostInstance->MmcHost;
118 Argument = EMMC_CMD6_ARG_ACCESS (3) | EMMC_CMD6_ARG_INDEX (ExtCmdIndex) |
119 EMMC_CMD6_ARG_VALUE (Value) | EMMC_CMD6_ARG_CMD_SET (1);
120 Status = Host->SendCommand (Host, MMC_CMD6, Argument);
121 if (EFI_ERROR (Status)) {
122 DEBUG ((DEBUG_ERROR, "EmmcSetEXTCSD(): Failed to send CMD6, Status=%r.\n", Status));
123 return Status;
124 }
125
126 // Make sure device exiting prog mode
127 do {
128 Status = EmmcGetDeviceState (MmcHostInstance, &State);
129 if (EFI_ERROR (Status)) {
130 DEBUG ((DEBUG_ERROR, "EmmcSetEXTCSD(): Failed to get device state, Status=%r.\n", Status));
131 return Status;
132 }
133 } while (State == EMMC_PRG_STATE);
134
135 return EFI_SUCCESS;
136 }
137
138 STATIC
139 EFI_STATUS
140 EFIAPI
141 EmmcIdentificationMode (
142 IN MMC_HOST_INSTANCE *MmcHostInstance,
143 IN OCR_RESPONSE Response
144 )
145 {
146 EFI_MMC_HOST_PROTOCOL *Host;
147 EFI_BLOCK_IO_MEDIA *Media;
148 EFI_STATUS Status;
149 EMMC_DEVICE_STATE State;
150 UINT32 RCA;
151
152 Host = MmcHostInstance->MmcHost;
153 Media = MmcHostInstance->BlockIo.Media;
154
155 // Fetch card identity register
156 Status = Host->SendCommand (Host, MMC_CMD2, 0);
157 if (EFI_ERROR (Status)) {
158 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Failed to send CMD2, Status=%r.\n", Status));
159 return Status;
160 }
161
162 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CIDData));
163 if (EFI_ERROR (Status)) {
164 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): CID retrieval error, Status=%r.\n", Status));
165 return Status;
166 }
167
168 // Assign a relative address value to the card
169 MmcHostInstance->CardInfo.RCA = ++mEmmcRcaCount; // TODO: might need a more sophisticated way of doing this
170 RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
171 Status = Host->SendCommand (Host, MMC_CMD3, RCA);
172 if (EFI_ERROR (Status)) {
173 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): RCA set error, Status=%r.\n", Status));
174 return Status;
175 }
176
177 // Fetch card specific data
178 Status = Host->SendCommand (Host, MMC_CMD9, RCA);
179 if (EFI_ERROR (Status)) {
180 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Failed to send CMD9, Status=%r.\n", Status));
181 return Status;
182 }
183
184 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CSDData));
185 if (EFI_ERROR (Status)) {
186 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): CSD retrieval error, Status=%r.\n", Status));
187 return Status;
188 }
189
190 // Select the card
191 Status = Host->SendCommand (Host, MMC_CMD7, RCA);
192 if (EFI_ERROR (Status)) {
193 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Card selection error, Status=%r.\n", Status));
194 }
195
196 if (MMC_HOST_HAS_SETIOS (Host)) {
197 // Set 1-bit bus width
198 Status = Host->SetIos (Host, 0, 1, EMMCBACKWARD);
199 if (EFI_ERROR (Status)) {
200 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Set 1-bit bus width error, Status=%r.\n", Status));
201 return Status;
202 }
203
204 // Set 1-bit bus width for EXTCSD
205 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, EMMC_BUS_WIDTH_1BIT);
206 if (EFI_ERROR (Status)) {
207 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Set extcsd bus width error, Status=%r.\n", Status));
208 return Status;
209 }
210 }
211
212 // Fetch ECSD
213 MmcHostInstance->CardInfo.ECSDData = AllocatePages (EFI_SIZE_TO_PAGES (sizeof (ECSD)));
214 if (MmcHostInstance->CardInfo.ECSDData == NULL) {
215 return EFI_OUT_OF_RESOURCES;
216 }
217
218 Status = Host->SendCommand (Host, MMC_CMD8, 0);
219 if (EFI_ERROR (Status)) {
220 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): ECSD fetch error, Status=%r.\n", Status));
221 }
222
223 Status = Host->ReadBlockData (Host, 0, 512, (UINT32 *)MmcHostInstance->CardInfo.ECSDData);
224 if (EFI_ERROR (Status)) {
225 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): ECSD read error, Status=%r.\n", Status));
226 goto FreePageExit;
227 }
228
229 // Make sure device exiting data mode
230 do {
231 Status = EmmcGetDeviceState (MmcHostInstance, &State);
232 if (EFI_ERROR (Status)) {
233 DEBUG ((DEBUG_ERROR, "EmmcIdentificationMode(): Failed to get device state, Status=%r.\n", Status));
234 goto FreePageExit;
235 }
236 } while (State == EMMC_DATA_STATE);
237
238 // Set up media
239 Media->BlockSize = EMMC_CARD_SIZE; // 512-byte support is mandatory for eMMC cards
240 Media->MediaId = MmcHostInstance->CardInfo.CIDData.PSN;
241 Media->ReadOnly = MmcHostInstance->CardInfo.CSDData.PERM_WRITE_PROTECT;
242 Media->LogicalBlocksPerPhysicalBlock = 1;
243 Media->IoAlign = 4;
244 // Compute last block using bits [215:212] of the ECSD
245 Media->LastBlock = MmcHostInstance->CardInfo.ECSDData->SECTOR_COUNT - 1; // eMMC isn't supposed to report this for
246 // Cards <2GB in size, but the model does.
247
248 // Setup card type
249 MmcHostInstance->CardInfo.CardType = EMMC_CARD;
250 return EFI_SUCCESS;
251
252 FreePageExit:
253 FreePages (MmcHostInstance->CardInfo.ECSDData, EFI_SIZE_TO_PAGES (sizeof (ECSD)));
254 return Status;
255 }
256
257 STATIC
258 EFI_STATUS
259 InitializeEmmcDevice (
260 IN MMC_HOST_INSTANCE *MmcHostInstance
261 )
262 {
263 EFI_MMC_HOST_PROTOCOL *Host;
264 EFI_STATUS Status = EFI_SUCCESS;
265 ECSD *ECSDData;
266 UINT32 BusClockFreq, Idx, BusMode;
267 UINT32 TimingMode[4] = { EMMCHS52DDR1V2, EMMCHS52DDR1V8, EMMCHS52, EMMCHS26 };
268
269 Host = MmcHostInstance->MmcHost;
270 ECSDData = MmcHostInstance->CardInfo.ECSDData;
271 if (ECSDData->DEVICE_TYPE == EMMCBACKWARD) {
272 return EFI_SUCCESS;
273 }
274
275 if (!MMC_HOST_HAS_SETIOS (Host)) {
276 return EFI_SUCCESS;
277 }
278
279 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_HS_TIMING, EMMC_TIMING_HS);
280 if (EFI_ERROR (Status)) {
281 DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to switch high speed mode, Status:%r.\n", Status));
282 return Status;
283 }
284
285 for (Idx = 0; Idx < 4; Idx++) {
286 switch (TimingMode[Idx]) {
287 case EMMCHS52DDR1V2:
288 case EMMCHS52DDR1V8:
289 case EMMCHS52:
290 BusClockFreq = 52000000;
291 break;
292 case EMMCHS26:
293 BusClockFreq = 26000000;
294 break;
295 default:
296 return EFI_UNSUPPORTED;
297 }
298
299 Status = Host->SetIos (Host, BusClockFreq, 8, TimingMode[Idx]);
300 if (!EFI_ERROR (Status)) {
301 switch (TimingMode[Idx]) {
302 case EMMCHS52DDR1V2:
303 case EMMCHS52DDR1V8:
304 BusMode = EMMC_BUS_WIDTH_DDR_8BIT;
305 break;
306 case EMMCHS52:
307 case EMMCHS26:
308 BusMode = EMMC_BUS_WIDTH_8BIT;
309 break;
310 default:
311 return EFI_UNSUPPORTED;
312 }
313
314 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, BusMode);
315 if (EFI_ERROR (Status)) {
316 DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to set EXTCSD bus width, Status:%r\n", Status));
317 }
318
319 return Status;
320 }
321 }
322
323 return Status;
324 }
325
326 STATIC
327 UINT32
328 CreateSwitchCmdArgument (
329 IN UINT32 Mode,
330 IN UINT8 Group,
331 IN UINT8 Value
332 )
333 {
334 UINT32 Argument;
335
336 Argument = Mode << 31 | 0x00FFFFFF;
337 Argument &= ~(0xF << (Group * 4));
338 Argument |= Value << (Group * 4);
339
340 return Argument;
341 }
342
343 STATIC
344 EFI_STATUS
345 InitializeSdMmcDevice (
346 IN MMC_HOST_INSTANCE *MmcHostInstance
347 )
348 {
349 UINT32 CmdArg;
350 UINT32 Response[4];
351 UINT32 Buffer[128];
352 UINT32 Speed;
353 UINTN BlockSize;
354 UINTN CardSize;
355 UINTN NumBlocks;
356 BOOLEAN CccSwitch;
357 SCR Scr;
358 EFI_STATUS Status;
359 EFI_MMC_HOST_PROTOCOL *MmcHost;
360
361 Speed = SD_DEFAULT_SPEED;
362 MmcHost = MmcHostInstance->MmcHost;
363
364 // Send a command to get Card specific data
365 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
366 Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);
367 if (EFI_ERROR (Status)) {
368 DEBUG ((DEBUG_ERROR, "InitializeSdMmcDevice(MMC_CMD9): Error, Status=%r\n", Status));
369 return Status;
370 }
371
372 // Read Response
373 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD, Response);
374 if (EFI_ERROR (Status)) {
375 DEBUG ((DEBUG_ERROR, "InitializeSdMmcDevice(): Failed to receive CSD, Status=%r\n", Status));
376 return Status;
377 }
378
379 PrintCSD (Response);
380 if (MMC_CSD_GET_CCC (Response) & SD_CCC_SWITCH) {
381 CccSwitch = TRUE;
382 } else {
383 CccSwitch = FALSE;
384 }
385
386 if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {
387 CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response);
388 NumBlocks = ((CardSize + 1) * 1024);
389 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
390 } else {
391 CardSize = MMC_CSD_GET_DEVICESIZE (Response);
392 NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response) + 2));
393 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
394 }
395
396 // For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
397 if (BlockSize > 512) {
398 NumBlocks = MultU64x32 (NumBlocks, BlockSize / 512);
399 BlockSize = 512;
400 }
401
402 MmcHostInstance->BlockIo.Media->LastBlock = (NumBlocks - 1);
403 MmcHostInstance->BlockIo.Media->BlockSize = BlockSize;
404 MmcHostInstance->BlockIo.Media->ReadOnly = MmcHost->IsReadOnly (MmcHost);
405 MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;
406 MmcHostInstance->BlockIo.Media->MediaId++;
407
408 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
409 Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);
410 if (EFI_ERROR (Status)) {
411 DEBUG ((DEBUG_ERROR, "InitializeSdMmcDevice(MMC_CMD7): Error and Status = %r\n", Status));
412 return Status;
413 }
414
415 Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg);
416 if (EFI_ERROR (Status)) {
417 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
418 return Status;
419 }
420
421 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R1, Response);
422 if (EFI_ERROR (Status)) {
423 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
424 return Status;
425 }
426
427 if ((Response[0] & MMC_STATUS_APP_CMD) == 0) {
428 return EFI_SUCCESS;
429 }
430
431 /* SCR */
432 Status = MmcHost->SendCommand (MmcHost, MMC_ACMD51, 0);
433 if (EFI_ERROR (Status)) {
434 DEBUG ((DEBUG_ERROR, "%a(MMC_ACMD51): Error and Status = %r\n", __func__, Status));
435 return Status;
436 } else {
437 Status = MmcHost->ReadBlockData (MmcHost, 0, 8, Buffer);
438 if (EFI_ERROR (Status)) {
439 DEBUG ((DEBUG_ERROR, "%a(MMC_ACMD51): ReadBlockData Error and Status = %r\n", __func__, Status));
440 return Status;
441 }
442
443 CopyMem (&Scr, Buffer, 8);
444 if (Scr.SD_SPEC == 2) {
445 if (Scr.SD_SPEC3 == 1) {
446 if (Scr.SD_SPEC4 == 1) {
447 DEBUG ((DEBUG_INFO, "Found SD Card for Spec Version 4.xx\n"));
448 } else {
449 DEBUG ((DEBUG_INFO, "Found SD Card for Spec Version 3.0x\n"));
450 }
451 } else {
452 if (Scr.SD_SPEC4 == 0) {
453 DEBUG ((DEBUG_INFO, "Found SD Card for Spec Version 2.0\n"));
454 } else {
455 DEBUG ((DEBUG_ERROR, "Found invalid SD Card\n"));
456 }
457 }
458 } else {
459 if ((Scr.SD_SPEC3 == 0) && (Scr.SD_SPEC4 == 0)) {
460 if (Scr.SD_SPEC == 1) {
461 DEBUG ((DEBUG_INFO, "Found SD Card for Spec Version 1.10\n"));
462 } else {
463 DEBUG ((DEBUG_INFO, "Found SD Card for Spec Version 1.0\n"));
464 }
465 } else {
466 DEBUG ((DEBUG_ERROR, "Found invalid SD Card\n"));
467 }
468 }
469 }
470
471 if (CccSwitch) {
472 /* SD Switch, Mode:0, Group:0, Value:0 */
473 CmdArg = CreateSwitchCmdArgument (0, 0, 0);
474 Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, CmdArg);
475 if (EFI_ERROR (Status)) {
476 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
477 return Status;
478 } else {
479 Status = MmcHost->ReadBlockData (MmcHost, 0, SWITCH_CMD_DATA_LENGTH, Buffer);
480 if (EFI_ERROR (Status)) {
481 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): ReadBlockData Error and Status = %r\n", __FUNCTION__, Status));
482 return Status;
483 }
484 }
485
486 if (!(Buffer[3] & SD_HIGH_SPEED_SUPPORTED)) {
487 DEBUG ((DEBUG_INFO, "%a : High Speed not supported by Card\n", __FUNCTION__));
488 } else {
489 Speed = SD_HIGH_SPEED;
490
491 /* SD Switch, Mode:1, Group:0, Value:1 */
492 CmdArg = CreateSwitchCmdArgument (1, 0, 1);
493 Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, CmdArg);
494 if (EFI_ERROR (Status)) {
495 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
496 return Status;
497 } else {
498 Status = MmcHost->ReadBlockData (MmcHost, 0, SWITCH_CMD_DATA_LENGTH, Buffer);
499 if (EFI_ERROR (Status)) {
500 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): ReadBlockData Error and Status = %r\n", __FUNCTION__, Status));
501 return Status;
502 }
503
504 if ((Buffer[4] & SWITCH_CMD_SUCCESS_MASK) != 0x01000000) {
505 DEBUG ((DEBUG_ERROR, "Problem switching SD card into high-speed mode\n"));
506 return Status;
507 }
508 }
509 }
510 }
511
512 if (Scr.SD_BUS_WIDTHS & SD_BUS_WIDTH_4BIT) {
513 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
514 Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, CmdArg);
515 if (EFI_ERROR (Status)) {
516 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD55): Error and Status = %r\n", __FUNCTION__, Status));
517 return Status;
518 }
519
520 /* Width: 4 */
521 Status = MmcHost->SendCommand (MmcHost, MMC_CMD6, 2);
522 if (EFI_ERROR (Status)) {
523 DEBUG ((DEBUG_ERROR, "%a (MMC_CMD6): Error and Status = %r\n", __FUNCTION__, Status));
524 return Status;
525 }
526 }
527
528 if (MMC_HOST_HAS_SETIOS (MmcHost)) {
529 Status = MmcHost->SetIos (MmcHost, Speed, BUSWIDTH_4, EMMCBACKWARD);
530 if (EFI_ERROR (Status)) {
531 DEBUG ((DEBUG_ERROR, "%a (SetIos): Error and Status = %r\n", __FUNCTION__, Status));
532 return Status;
533 }
534 }
535
536 return EFI_SUCCESS;
537 }
538
539 STATIC
540 EFI_STATUS
541 EFIAPI
542 MmcIdentificationMode (
543 IN MMC_HOST_INSTANCE *MmcHostInstance
544 )
545 {
546 EFI_STATUS Status;
547 UINT32 Response[4];
548 UINTN Timeout;
549 UINTN CmdArg;
550 BOOLEAN IsHCS;
551 EFI_MMC_HOST_PROTOCOL *MmcHost;
552 OCR_RESPONSE OcrResponse;
553
554 MmcHost = MmcHostInstance->MmcHost;
555 CmdArg = 0;
556 IsHCS = FALSE;
557
558 if (MmcHost == NULL) {
559 return EFI_INVALID_PARAMETER;
560 }
561
562 // We can get into this function if we restart the identification mode
563 if (MmcHostInstance->State == MmcHwInitializationState) {
564 // Initialize the MMC Host HW
565 Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);
566 if (EFI_ERROR (Status)) {
567 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState, Status=%r.\n", Status));
568 return Status;
569 }
570 }
571
572 Status = MmcHost->SendCommand (MmcHost, MMC_CMD0, 0);
573 if (EFI_ERROR (Status)) {
574 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(MMC_CMD0): Error, Status=%r.\n", Status));
575 return Status;
576 }
577
578 Status = MmcNotifyState (MmcHostInstance, MmcIdleState);
579 if (EFI_ERROR (Status)) {
580 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Error MmcIdleState, Status=%r.\n", Status));
581 return Status;
582 }
583
584 // Send CMD1 to get OCR (MMC)
585 // This command only valid for MMC and eMMC
586 Timeout = MAX_RETRY_COUNT;
587 do {
588 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, EMMC_CMD1_CAPACITY_GREATER_THAN_2GB);
589 if (EFI_ERROR (Status)) {
590 break;
591 }
592
593 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, (UINT32 *)&OcrResponse);
594 if (EFI_ERROR (Status)) {
595 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
596 return Status;
597 }
598
599 Timeout--;
600 } while (!OcrResponse.Ocr.PowerUp && (Timeout > 0));
601
602 if (Status == EFI_SUCCESS) {
603 if (!OcrResponse.Ocr.PowerUp) {
604 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(MMC_CMD1): Card initialisation failure, Status=%r.\n", Status));
605 return EFI_DEVICE_ERROR;
606 }
607
608 OcrResponse.Ocr.PowerUp = 0;
609 if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB) {
610 MmcHostInstance->CardInfo.OCRData.AccessMode = BIT1;
611 } else {
612 MmcHostInstance->CardInfo.OCRData.AccessMode = 0x0;
613 }
614
615 // Check whether MMC or eMMC
616 if ((OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB) ||
617 (OcrResponse.Raw == EMMC_CMD1_CAPACITY_LESS_THAN_2GB))
618 {
619 return EmmcIdentificationMode (MmcHostInstance, OcrResponse);
620 }
621 }
622
623 // Are we using SDIO ?
624 Status = MmcHost->SendCommand (MmcHost, MMC_CMD5, 0);
625 if (Status == EFI_SUCCESS) {
626 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported, Status=%r.\n", Status));
627 return EFI_UNSUPPORTED;
628 }
629
630 // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
631 CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);
632 Status = MmcHost->SendCommand (MmcHost, MMC_CMD8, CmdArg);
633 if (Status == EFI_SUCCESS) {
634 DEBUG ((DEBUG_ERROR, "Card is SD2.0 => Supports high capacity\n"));
635 IsHCS = TRUE;
636 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R7, Response);
637 if (EFI_ERROR (Status)) {
638 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive response to CMD8, Status=%r.\n", Status));
639 return Status;
640 }
641
642 PrintResponseR1 (Response[0]);
643 // Check if it is valid response
644 if (Response[0] != CmdArg) {
645 DEBUG ((DEBUG_ERROR, "The Card is not usable\n"));
646 return EFI_UNSUPPORTED;
647 }
648 } else {
649 DEBUG ((DEBUG_ERROR, "Not a SD2.0 Card\n"));
650 }
651
652 // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
653 Timeout = MAX_RETRY_COUNT;
654 while (Timeout > 0) {
655 // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
656 Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, 0);
657 if (Status == EFI_SUCCESS) {
658 DEBUG ((DEBUG_INFO, "Card should be SD\n"));
659 if (IsHCS) {
660 MmcHostInstance->CardInfo.CardType = SD_CARD_2;
661 } else {
662 MmcHostInstance->CardInfo.CardType = SD_CARD;
663 }
664
665 // Note: The first time CmdArg will be zero
666 CmdArg = ((UINTN *)&(MmcHostInstance->CardInfo.OCRData))[0];
667 if (IsHCS) {
668 CmdArg |= BIT30;
669 }
670
671 Status = MmcHost->SendCommand (MmcHost, MMC_ACMD41, CmdArg);
672 if (!EFI_ERROR (Status)) {
673 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
674 if (EFI_ERROR (Status)) {
675 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
676 return Status;
677 }
678
679 ((UINT32 *)&(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
680 }
681 } else {
682 DEBUG ((DEBUG_INFO, "Card should be MMC\n"));
683 MmcHostInstance->CardInfo.CardType = MMC_CARD;
684
685 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, 0x800000);
686 if (!EFI_ERROR (Status)) {
687 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
688 if (EFI_ERROR (Status)) {
689 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
690 return Status;
691 }
692
693 ((UINT32 *)&(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
694 }
695 }
696
697 if (!EFI_ERROR (Status)) {
698 if (!MmcHostInstance->CardInfo.OCRData.PowerUp) {
699 gBS->Stall (1);
700 Timeout--;
701 } else {
702 if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {
703 MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;
704 DEBUG ((DEBUG_ERROR, "High capacity card.\n"));
705 }
706
707 break; // The MMC/SD card is ready. Continue the Identification Mode
708 }
709 } else {
710 gBS->Stall (1);
711 Timeout--;
712 }
713 }
714
715 if (Timeout == 0) {
716 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(): No Card\n"));
717 return EFI_NO_MEDIA;
718 } else {
719 PrintOCR (Response[0]);
720 }
721
722 Status = MmcNotifyState (MmcHostInstance, MmcReadyState);
723 if (EFI_ERROR (Status)) {
724 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));
725 return Status;
726 }
727
728 Status = MmcHost->SendCommand (MmcHost, MMC_CMD2, 0);
729 if (EFI_ERROR (Status)) {
730 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));
731 return Status;
732 }
733
734 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CID, Response);
735 if (EFI_ERROR (Status)) {
736 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive CID, Status=%r.\n", Status));
737 return Status;
738 }
739
740 PrintCID (Response);
741
742 Status = MmcHost->NotifyState (MmcHost, MmcIdentificationState);
743 if (EFI_ERROR (Status)) {
744 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
745 return Status;
746 }
747
748 //
749 // Note, SD specifications say that "if the command execution causes a state change, it
750 // will be visible to the host in the response to the next command"
751 // The status returned for this CMD3 will be 2 - identification
752 //
753 CmdArg = 1;
754 Status = MmcHost->SendCommand (MmcHost, MMC_CMD3, CmdArg);
755 if (EFI_ERROR (Status)) {
756 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));
757 return Status;
758 }
759
760 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_RCA, Response);
761 if (EFI_ERROR (Status)) {
762 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Failed to receive RCA, Status=%r.\n", Status));
763 return Status;
764 }
765
766 PrintRCA (Response[0]);
767
768 // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
769 if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {
770 MmcHostInstance->CardInfo.RCA = Response[0] >> 16;
771 } else {
772 MmcHostInstance->CardInfo.RCA = CmdArg;
773 }
774
775 Status = MmcNotifyState (MmcHostInstance, MmcStandByState);
776 if (EFI_ERROR (Status)) {
777 DEBUG ((DEBUG_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));
778 return Status;
779 }
780
781 return EFI_SUCCESS;
782 }
783
784 EFI_STATUS
785 InitializeMmcDevice (
786 IN MMC_HOST_INSTANCE *MmcHostInstance
787 )
788 {
789 EFI_STATUS Status;
790 EFI_MMC_HOST_PROTOCOL *MmcHost;
791 UINTN BlockCount;
792
793 BlockCount = 1;
794 MmcHost = MmcHostInstance->MmcHost;
795
796 Status = MmcIdentificationMode (MmcHostInstance);
797 if (EFI_ERROR (Status)) {
798 DEBUG ((DEBUG_ERROR, "InitializeMmcDevice(): Error in Identification Mode, Status=%r\n", Status));
799 return Status;
800 }
801
802 Status = MmcNotifyState (MmcHostInstance, MmcTransferState);
803 if (EFI_ERROR (Status)) {
804 DEBUG ((DEBUG_ERROR, "InitializeMmcDevice(): Error MmcTransferState, Status=%r\n", Status));
805 return Status;
806 }
807
808 if (MmcHostInstance->CardInfo.CardType != EMMC_CARD) {
809 Status = InitializeSdMmcDevice (MmcHostInstance);
810 } else {
811 Status = InitializeEmmcDevice (MmcHostInstance);
812 }
813
814 if (EFI_ERROR (Status)) {
815 return Status;
816 }
817
818 // Set Block Length
819 Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);
820 if (EFI_ERROR (Status)) {
821 DEBUG ((
822 DEBUG_ERROR,
823 "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
824 MmcHostInstance->BlockIo.Media->BlockSize,
825 Status
826 ));
827 return Status;
828 }
829
830 // Block Count (not used). Could return an error for SD card
831 if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {
832 Status = MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);
833 if (EFI_ERROR (Status)) {
834 DEBUG ((DEBUG_ERROR, "InitializeMmcDevice(MMC_CMD23): Error, Status=%r\n", Status));
835 return Status;
836 }
837 }
838
839 return EFI_SUCCESS;
840 }