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