EmbeddedPkg/MmcDxe: invoke SetIos() protocol method to set speed and width
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / MmcIdentification.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
5 * This program and the accompanying materials
6 * are licensed and made available under the terms and conditions of the BSD License
7 * which accompanies this distribution. The full text of the license may be found at
8 * http://opensource.org/licenses/bsd-license.php
9 *
10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14
15 #include "Mmc.h"
16
17 typedef union {
18 UINT32 Raw;
19 OCR Ocr;
20 } OCR_RESPONSE;
21
22 #define MAX_RETRY_COUNT 1000
23 #define CMD_RETRY_COUNT 20
24 #define RCA_SHIFT_OFFSET 16
25 #define EMMC_CARD_SIZE 512
26 #define EMMC_ECSD_SIZE_OFFSET 53
27
28 #define EXTCSD_BUS_WIDTH 183
29 #define EXTCSD_HS_TIMING 185
30
31 #define EMMC_TIMING_BACKWARD 0
32 #define EMMC_TIMING_HS 1
33 #define EMMC_TIMING_HS200 2
34 #define EMMC_TIMING_HS400 3
35
36 #define EMMC_BUS_WIDTH_1BIT 0
37 #define EMMC_BUS_WIDTH_4BIT 1
38 #define EMMC_BUS_WIDTH_8BIT 2
39 #define EMMC_BUS_WIDTH_DDR_4BIT 5
40 #define EMMC_BUS_WIDTH_DDR_8BIT 6
41
42 #define EMMC_SWITCH_ERROR (1 << 7)
43
44 #define DEVICE_STATE(x) (((x) >> 9) & 0xf)
45 typedef enum _EMMC_DEVICE_STATE {
46 EMMC_IDLE_STATE = 0,
47 EMMC_READY_STATE,
48 EMMC_IDENT_STATE,
49 EMMC_STBY_STATE,
50 EMMC_TRAN_STATE,
51 EMMC_DATA_STATE,
52 EMMC_RCV_STATE,
53 EMMC_PRG_STATE,
54 EMMC_DIS_STATE,
55 EMMC_BTST_STATE,
56 EMMC_SLP_STATE
57 } EMMC_DEVICE_STATE;
58
59 UINT32 mEmmcRcaCount = 0;
60
61 STATIC
62 EFI_STATUS
63 EFIAPI
64 EmmcGetDeviceState (
65 IN MMC_HOST_INSTANCE *MmcHostInstance,
66 OUT EMMC_DEVICE_STATE *State
67 )
68 {
69 EFI_MMC_HOST_PROTOCOL *Host;
70 EFI_STATUS Status;
71 UINT32 Data, RCA;
72
73 if (State == NULL) {
74 return EFI_INVALID_PARAMETER;
75 }
76
77 Host = MmcHostInstance->MmcHost;
78 RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
79 Status = Host->SendCommand (Host, MMC_CMD13, RCA);
80 if (EFI_ERROR (Status)) {
81 DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get card status, Status=%r.\n", Status));
82 return Status;
83 }
84 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R1, &Data);
85 if (EFI_ERROR (Status)) {
86 DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to get response of CMD13, Status=%r.\n", Status));
87 return Status;
88 }
89 if (Data & EMMC_SWITCH_ERROR) {
90 DEBUG ((EFI_D_ERROR, "EmmcGetDeviceState(): Failed to switch expected mode, Status=%r.\n", Status));
91 return EFI_DEVICE_ERROR;
92 }
93 *State = DEVICE_STATE(Data);
94 return EFI_SUCCESS;
95 }
96
97 STATIC
98 EFI_STATUS
99 EFIAPI
100 EmmcSetEXTCSD (
101 IN MMC_HOST_INSTANCE *MmcHostInstance,
102 UINT32 ExtCmdIndex,
103 UINT32 Value
104 )
105 {
106 EFI_MMC_HOST_PROTOCOL *Host;
107 EMMC_DEVICE_STATE State;
108 EFI_STATUS Status;
109 UINT32 Argument;
110
111 Host = MmcHostInstance->MmcHost;
112 Argument = EMMC_CMD6_ARG_ACCESS(3) | EMMC_CMD6_ARG_INDEX(ExtCmdIndex) |
113 EMMC_CMD6_ARG_VALUE(Value) | EMMC_CMD6_ARG_CMD_SET(1);
114 Status = Host->SendCommand (Host, MMC_CMD6, Argument);
115 if (EFI_ERROR (Status)) {
116 DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to send CMD6, Status=%r.\n", Status));
117 return Status;
118 }
119 // Make sure device exiting prog mode
120 do {
121 Status = EmmcGetDeviceState (MmcHostInstance, &State);
122 if (EFI_ERROR (Status)) {
123 DEBUG ((EFI_D_ERROR, "EmmcSetEXTCSD(): Failed to get device state, Status=%r.\n", Status));
124 return Status;
125 }
126 } while (State == EMMC_PRG_STATE);
127 return EFI_SUCCESS;
128 }
129
130 STATIC
131 EFI_STATUS
132 EFIAPI
133 EmmcIdentificationMode (
134 IN MMC_HOST_INSTANCE *MmcHostInstance,
135 IN OCR_RESPONSE Response
136 )
137 {
138 EFI_MMC_HOST_PROTOCOL *Host;
139 EFI_BLOCK_IO_MEDIA *Media;
140 EFI_STATUS Status;
141 EMMC_DEVICE_STATE State;
142 UINT32 RCA;
143
144 Host = MmcHostInstance->MmcHost;
145 Media = MmcHostInstance->BlockIo.Media;
146
147 // Fetch card identity register
148 Status = Host->SendCommand (Host, MMC_CMD2, 0);
149 if (EFI_ERROR (Status)) {
150 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD2, Status=%r.\n", Status));
151 return Status;
152 }
153
154 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CIDData));
155 if (EFI_ERROR (Status)) {
156 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CID retrieval error, Status=%r.\n", Status));
157 return Status;
158 }
159
160 // Assign a relative address value to the card
161 MmcHostInstance->CardInfo.RCA = ++mEmmcRcaCount; // TODO: might need a more sophisticated way of doing this
162 RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
163 Status = Host->SendCommand (Host, MMC_CMD3, RCA);
164 if (EFI_ERROR (Status)) {
165 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): RCA set error, Status=%r.\n", Status));
166 return Status;
167 }
168
169 // Fetch card specific data
170 Status = Host->SendCommand (Host, MMC_CMD9, RCA);
171 if (EFI_ERROR (Status)) {
172 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD9, Status=%r.\n", Status));
173 return Status;
174 }
175
176 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CSDData));
177 if (EFI_ERROR (Status)) {
178 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CSD retrieval error, Status=%r.\n", Status));
179 return Status;
180 }
181
182 // Select the card
183 Status = Host->SendCommand (Host, MMC_CMD7, RCA);
184 if (EFI_ERROR (Status)) {
185 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Card selection error, Status=%r.\n", Status));
186 }
187
188 if (MMC_HOST_HAS_SETIOS(Host)) {
189 // Set 1-bit bus width
190 Status = Host->SetIos (Host, 0, 1, EMMCBACKWARD);
191 if (EFI_ERROR (Status)) {
192 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Set 1-bit bus width error, Status=%r.\n", Status));
193 return Status;
194 }
195
196 // Set 1-bit bus width for EXTCSD
197 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, EMMC_BUS_WIDTH_1BIT);
198 if (EFI_ERROR (Status)) {
199 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Set extcsd bus width error, Status=%r.\n", Status));
200 return Status;
201 }
202 }
203
204 // Fetch ECSD
205 Status = Host->SendCommand (Host, MMC_CMD8, RCA);
206 if (EFI_ERROR (Status)) {
207 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD fetch error, Status=%r.\n", Status));
208 }
209
210 Status = Host->ReadBlockData (Host, 0, 512, (UINT32 *)&(MmcHostInstance->CardInfo.ECSDData));
211 if (EFI_ERROR (Status)) {
212 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD read error, Status=%r.\n", Status));
213 return Status;
214 }
215
216 // Make sure device exiting data mode
217 do {
218 Status = EmmcGetDeviceState (MmcHostInstance, &State);
219 if (EFI_ERROR (Status)) {
220 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to get device state, Status=%r.\n", Status));
221 return Status;
222 }
223 } while (State == EMMC_DATA_STATE);
224
225 // Set up media
226 Media->BlockSize = EMMC_CARD_SIZE; // 512-byte support is mandatory for eMMC cards
227 Media->MediaId = MmcHostInstance->CardInfo.CIDData.PSN;
228 Media->ReadOnly = MmcHostInstance->CardInfo.CSDData.PERM_WRITE_PROTECT;
229 Media->LogicalBlocksPerPhysicalBlock = 1;
230 Media->IoAlign = 4;
231 // Compute last block using bits [215:212] of the ECSD
232 Media->LastBlock = MmcHostInstance->CardInfo.ECSDData.SECTOR_COUNT - 1; // eMMC isn't supposed to report this for
233 // Cards <2GB in size, but the model does.
234
235 // Setup card type
236 MmcHostInstance->CardInfo.CardType = EMMC_CARD;
237 return EFI_SUCCESS;
238 }
239
240 STATIC
241 EFI_STATUS
242 InitializeEmmcDevice (
243 IN MMC_HOST_INSTANCE *MmcHostInstance
244 )
245 {
246 EFI_MMC_HOST_PROTOCOL *Host;
247 EFI_STATUS Status = EFI_SUCCESS;
248 ECSD *ECSDData;
249 UINT32 BusClockFreq, Idx;
250 UINT32 TimingMode[4] = {EMMCHS52DDR1V2, EMMCHS52DDR1V8, EMMCHS52, EMMCHS26};
251
252 Host = MmcHostInstance->MmcHost;
253 ECSDData = &MmcHostInstance->CardInfo.ECSDData;
254 if (ECSDData->DEVICE_TYPE == EMMCBACKWARD)
255 return EFI_SUCCESS;
256
257 if (!MMC_HOST_HAS_SETIOS(Host)) {
258 return EFI_SUCCESS;
259 }
260 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_HS_TIMING, EMMC_TIMING_HS);
261 if (EFI_ERROR (Status)) {
262 DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to switch high speed mode, Status:%r.\n", Status));
263 return Status;
264 }
265
266 for (Idx = 0; Idx < 4; Idx++) {
267 switch (TimingMode[Idx]) {
268 case EMMCHS52DDR1V2:
269 case EMMCHS52DDR1V8:
270 case EMMCHS52:
271 BusClockFreq = 52000000;
272 break;
273 case EMMCHS26:
274 BusClockFreq = 26000000;
275 break;
276 default:
277 return EFI_UNSUPPORTED;
278 }
279 Status = Host->SetIos (Host, BusClockFreq, 8, TimingMode[Idx]);
280 if (!EFI_ERROR (Status)) {
281 Status = EmmcSetEXTCSD (MmcHostInstance, EXTCSD_BUS_WIDTH, EMMC_BUS_WIDTH_DDR_8BIT);
282 if (EFI_ERROR (Status)) {
283 DEBUG ((DEBUG_ERROR, "InitializeEmmcDevice(): Failed to set EXTCSD bus width, Status:%r\n", Status));
284 }
285 return Status;
286 }
287 }
288 return Status;
289 }
290
291 STATIC
292 EFI_STATUS
293 InitializeSdMmcDevice (
294 IN MMC_HOST_INSTANCE *MmcHostInstance
295 )
296 {
297 UINT32 CmdArg;
298 UINT32 Response[4];
299 UINTN BlockSize;
300 UINTN CardSize;
301 UINTN NumBlocks;
302 EFI_STATUS Status;
303 EFI_MMC_HOST_PROTOCOL *MmcHost;
304
305 MmcHost = MmcHostInstance->MmcHost;
306
307 // Send a command to get Card specific data
308 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
309 Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);
310 if (EFI_ERROR (Status)) {
311 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD9): Error, Status=%r\n", Status));
312 return Status;
313 }
314
315 // Read Response
316 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD, Response);
317 if (EFI_ERROR (Status)) {
318 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(): Failed to receive CSD, Status=%r\n", Status));
319 return Status;
320 }
321 PrintCSD (Response);
322
323 if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {
324 CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response);
325 NumBlocks = ((CardSize + 1) * 1024);
326 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
327 } else {
328 CardSize = MMC_CSD_GET_DEVICESIZE (Response);
329 NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response) + 2));
330 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
331 }
332
333 // For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
334 if (BlockSize > 512) {
335 NumBlocks = MultU64x32 (NumBlocks, BlockSize / 512);
336 BlockSize = 512;
337 }
338
339 MmcHostInstance->BlockIo.Media->LastBlock = (NumBlocks - 1);
340 MmcHostInstance->BlockIo.Media->BlockSize = BlockSize;
341 MmcHostInstance->BlockIo.Media->ReadOnly = MmcHost->IsReadOnly (MmcHost);
342 MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;
343 MmcHostInstance->BlockIo.Media->MediaId++;
344
345 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
346 Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);
347 if (EFI_ERROR (Status)) {
348 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD7): Error and Status = %r\n", Status));
349 return Status;
350 }
351
352 return EFI_SUCCESS;
353 }
354
355 STATIC
356 EFI_STATUS
357 EFIAPI
358 MmcIdentificationMode (
359 IN MMC_HOST_INSTANCE *MmcHostInstance
360 )
361 {
362 EFI_STATUS Status;
363 UINT32 Response[4];
364 UINTN Timeout;
365 UINTN CmdArg;
366 BOOLEAN IsHCS;
367 EFI_MMC_HOST_PROTOCOL *MmcHost;
368 OCR_RESPONSE OcrResponse;
369
370 MmcHost = MmcHostInstance->MmcHost;
371 CmdArg = 0;
372 IsHCS = FALSE;
373
374 if (MmcHost == NULL) {
375 return EFI_INVALID_PARAMETER;
376 }
377
378 // We can get into this function if we restart the identification mode
379 if (MmcHostInstance->State == MmcHwInitializationState) {
380 // Initialize the MMC Host HW
381 Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);
382 if (EFI_ERROR (Status)) {
383 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState, Status=%r.\n", Status));
384 return Status;
385 }
386 }
387
388 Status = MmcHost->SendCommand (MmcHost, MMC_CMD0, 0);
389 if (EFI_ERROR (Status)) {
390 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD0): Error, Status=%r.\n", Status));
391 return Status;
392 }
393 Status = MmcNotifyState (MmcHostInstance, MmcIdleState);
394 if (EFI_ERROR (Status)) {
395 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdleState, Status=%r.\n", Status));
396 return Status;
397 }
398
399 // Send CMD1 to get OCR (MMC)
400 // This command only valid for MMC and eMMC
401 Timeout = MAX_RETRY_COUNT;
402 do {
403 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, EMMC_CMD1_CAPACITY_GREATER_THAN_2GB);
404 if (EFI_ERROR (Status))
405 break;
406 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, (UINT32 *)&OcrResponse);
407 if (EFI_ERROR (Status)) {
408 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
409 return Status;
410 }
411 Timeout--;
412 } while (!OcrResponse.Ocr.PowerUp && (Timeout > 0));
413 if (Status == EFI_SUCCESS) {
414 if (!OcrResponse.Ocr.PowerUp) {
415 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD1): Card initialisation failure, Status=%r.\n", Status));
416 return EFI_DEVICE_ERROR;
417 }
418 OcrResponse.Ocr.PowerUp = 0;
419 if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB) {
420 MmcHostInstance->CardInfo.OCRData.AccessMode = BIT1;
421 }
422 else {
423 MmcHostInstance->CardInfo.OCRData.AccessMode = 0x0;
424 }
425 // Check whether MMC or eMMC
426 if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB ||
427 OcrResponse.Raw == EMMC_CMD1_CAPACITY_LESS_THAN_2GB) {
428 return EmmcIdentificationMode (MmcHostInstance, OcrResponse);
429 }
430 }
431
432 // Are we using SDIO ?
433 Status = MmcHost->SendCommand (MmcHost, MMC_CMD5, 0);
434 if (Status == EFI_SUCCESS) {
435 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported, Status=%r.\n", Status));
436 return EFI_UNSUPPORTED;
437 }
438
439 // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
440 CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);
441 Status = MmcHost->SendCommand (MmcHost, MMC_CMD8, CmdArg);
442 if (Status == EFI_SUCCESS) {
443 DEBUG ((EFI_D_ERROR, "Card is SD2.0 => Supports high capacity\n"));
444 IsHCS = TRUE;
445 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R7, Response);
446 if (EFI_ERROR (Status)) {
447 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive response to CMD8, Status=%r.\n", Status));
448 return Status;
449 }
450 PrintResponseR1 (Response[0]);
451 // Check if it is valid response
452 if (Response[0] != CmdArg) {
453 DEBUG ((EFI_D_ERROR, "The Card is not usable\n"));
454 return EFI_UNSUPPORTED;
455 }
456 } else {
457 DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));
458 }
459
460 // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
461 Timeout = MAX_RETRY_COUNT;
462 while (Timeout > 0) {
463 // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
464 Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, 0);
465 if (Status == EFI_SUCCESS) {
466 DEBUG ((EFI_D_INFO, "Card should be SD\n"));
467 if (IsHCS) {
468 MmcHostInstance->CardInfo.CardType = SD_CARD_2;
469 } else {
470 MmcHostInstance->CardInfo.CardType = SD_CARD;
471 }
472
473 // Note: The first time CmdArg will be zero
474 CmdArg = ((UINTN *) &(MmcHostInstance->CardInfo.OCRData))[0];
475 if (IsHCS) {
476 CmdArg |= BIT30;
477 }
478 Status = MmcHost->SendCommand (MmcHost, MMC_ACMD41, CmdArg);
479 if (!EFI_ERROR (Status)) {
480 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
481 if (EFI_ERROR (Status)) {
482 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
483 return Status;
484 }
485 ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
486 }
487 } else {
488 DEBUG ((EFI_D_INFO, "Card should be MMC\n"));
489 MmcHostInstance->CardInfo.CardType = MMC_CARD;
490
491 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, 0x800000);
492 if (!EFI_ERROR (Status)) {
493 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
494 if (EFI_ERROR (Status)) {
495 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
496 return Status;
497 }
498 ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
499 }
500 }
501
502 if (!EFI_ERROR (Status)) {
503 if (!MmcHostInstance->CardInfo.OCRData.PowerUp) {
504 gBS->Stall (1);
505 Timeout--;
506 } else {
507 if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {
508 MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;
509 DEBUG ((EFI_D_ERROR, "High capacity card.\n"));
510 }
511 break; // The MMC/SD card is ready. Continue the Identification Mode
512 }
513 } else {
514 gBS->Stall (1);
515 Timeout--;
516 }
517 }
518
519 if (Timeout == 0) {
520 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));
521 return EFI_NO_MEDIA;
522 } else {
523 PrintOCR (Response[0]);
524 }
525
526 Status = MmcNotifyState (MmcHostInstance, MmcReadyState);
527 if (EFI_ERROR (Status)) {
528 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));
529 return Status;
530 }
531
532 Status = MmcHost->SendCommand (MmcHost, MMC_CMD2, 0);
533 if (EFI_ERROR (Status)) {
534 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));
535 return Status;
536 }
537 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CID, Response);
538 if (EFI_ERROR (Status)) {
539 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive CID, Status=%r.\n", Status));
540 return Status;
541 }
542
543 PrintCID (Response);
544
545 Status = MmcHost->NotifyState (MmcHost, MmcIdentificationState);
546 if (EFI_ERROR (Status)) {
547 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
548 return Status;
549 }
550
551 //
552 // Note, SD specifications say that "if the command execution causes a state change, it
553 // will be visible to the host in the response to the next command"
554 // The status returned for this CMD3 will be 2 - identification
555 //
556 CmdArg = 1;
557 Status = MmcHost->SendCommand (MmcHost, MMC_CMD3, CmdArg);
558 if (EFI_ERROR (Status)) {
559 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));
560 return Status;
561 }
562
563 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_RCA, Response);
564 if (EFI_ERROR (Status)) {
565 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive RCA, Status=%r.\n", Status));
566 return Status;
567 }
568 PrintRCA (Response[0]);
569
570 // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
571 if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {
572 MmcHostInstance->CardInfo.RCA = Response[0] >> 16;
573 } else {
574 MmcHostInstance->CardInfo.RCA = CmdArg;
575 }
576 Status = MmcNotifyState (MmcHostInstance, MmcStandByState);
577 if (EFI_ERROR (Status)) {
578 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));
579 return Status;
580 }
581
582 return EFI_SUCCESS;
583 }
584
585 EFI_STATUS
586 InitializeMmcDevice (
587 IN MMC_HOST_INSTANCE *MmcHostInstance
588 )
589 {
590 EFI_STATUS Status;
591 EFI_MMC_HOST_PROTOCOL *MmcHost;
592 UINTN BlockCount;
593
594 BlockCount = 1;
595 MmcHost = MmcHostInstance->MmcHost;
596
597 Status = MmcIdentificationMode (MmcHostInstance);
598 if (EFI_ERROR (Status)) {
599 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error in Identification Mode, Status=%r\n", Status));
600 return Status;
601 }
602
603 Status = MmcNotifyState (MmcHostInstance, MmcTransferState);
604 if (EFI_ERROR (Status)) {
605 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error MmcTransferState, Status=%r\n", Status));
606 return Status;
607 }
608
609 if (MmcHostInstance->CardInfo.CardType != EMMC_CARD) {
610 Status = InitializeSdMmcDevice (MmcHostInstance);
611 } else {
612 Status = InitializeEmmcDevice (MmcHostInstance);
613 }
614 if (EFI_ERROR (Status)) {
615 return Status;
616 }
617
618 // Set Block Length
619 Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);
620 if (EFI_ERROR (Status)) {
621 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
622 MmcHostInstance->BlockIo.Media->BlockSize, Status));
623 return Status;
624 }
625
626 // Block Count (not used). Could return an error for SD card
627 if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {
628 Status = MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);
629 if (EFI_ERROR (Status)) {
630 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD23): Error, Status=%r\n", Status));
631 return Status;
632 }
633 }
634
635 return EFI_SUCCESS;
636 }