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