Home | History | Annotate | Download | only in SDMediaDeviceDxe
      1 /** @file
      2 
      3 MMC/SD transfer specific functions
      4 
      5 Copyright (c) 2013-2015 Intel Corporation.
      6 
      7 This program and the accompanying materials
      8 are licensed and made available under the terms and conditions of the BSD License
      9 which accompanies this distribution.  The full text of the license may be found at
     10 http://opensource.org/licenses/bsd-license.php
     11 
     12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     14 
     15 **/
     16 
     17 #include "SDMediaDevice.h"
     18 
     19 /**
     20   Check card status, print the debug info and check the error
     21 
     22   @param  Status                Status got from card status register.
     23 
     24   @retval EFI_SUCCESS
     25   @retval EFI_DEVICE_ERROR
     26 
     27 **/
     28 EFI_STATUS
     29 CheckCardStatus (
     30   IN  UINT32    Status
     31   )
     32 {
     33   CARD_STATUS    *CardStatus;
     34   CardStatus = (CARD_STATUS*)(&Status);
     35 
     36   if (CardStatus->ADDRESS_OUT_OF_RANGE) {
     37     DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_OUT_OF_RANGE\n"));
     38   }
     39 
     40   if (CardStatus->ADDRESS_MISALIGN) {
     41     DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_MISALIGN\n"));
     42   }
     43 
     44   if (CardStatus->BLOCK_LEN_ERROR) {
     45     DEBUG ((EFI_D_ERROR, "CardStatus: BLOCK_LEN_ERROR\n"));
     46   }
     47 
     48   if (CardStatus->ERASE_SEQ_ERROR) {
     49     DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_SEQ_ERROR\n"));
     50   }
     51 
     52   if (CardStatus->ERASE_PARAM) {
     53     DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_PARAM\n"));
     54   }
     55 
     56   if (CardStatus->WP_VIOLATION) {
     57     DEBUG ((EFI_D_ERROR, "CardStatus: WP_VIOLATION\n"));
     58   }
     59 
     60   if (CardStatus->CARD_IS_LOCKED) {
     61     DEBUG ((EFI_D_ERROR, "CardStatus: CARD_IS_LOCKED\n"));
     62   }
     63 
     64   if (CardStatus->LOCK_UNLOCK_FAILED) {
     65     DEBUG ((EFI_D_ERROR, "CardStatus: LOCK_UNLOCK_FAILED\n"));
     66   }
     67 
     68   if (CardStatus->COM_CRC_ERROR) {
     69     DEBUG ((EFI_D_ERROR, "CardStatus: COM_CRC_ERROR\n"));
     70   }
     71 
     72   if (CardStatus->ILLEGAL_COMMAND) {
     73     DEBUG ((EFI_D_ERROR, "CardStatus: ILLEGAL_COMMAND\n"));
     74   }
     75 
     76   if (CardStatus->CARD_ECC_FAILED) {
     77     DEBUG ((EFI_D_ERROR, "CardStatus: CARD_ECC_FAILED\n"));
     78   }
     79 
     80   if (CardStatus->CC_ERROR) {
     81     DEBUG ((EFI_D_ERROR, "CardStatus: CC_ERROR\n"));
     82   }
     83 
     84   if (CardStatus->ERROR) {
     85     DEBUG ((EFI_D_ERROR, "CardStatus: ERROR\n"));
     86   }
     87 
     88   if (CardStatus->UNDERRUN) {
     89     DEBUG ((EFI_D_ERROR, "CardStatus: UNDERRUN\n"));
     90   }
     91 
     92   if (CardStatus->OVERRUN) {
     93     DEBUG ((EFI_D_ERROR, "CardStatus: OVERRUN\n"));
     94   }
     95 
     96   if (CardStatus->CID_CSD_OVERWRITE) {
     97     DEBUG ((EFI_D_ERROR, "CardStatus: CID_CSD_OVERWRITE\n"));
     98   }
     99 
    100   if (CardStatus->WP_ERASE_SKIP) {
    101     DEBUG ((EFI_D_ERROR, "CardStatus: WP_ERASE_SKIP\n"));
    102   }
    103 
    104   if (CardStatus->ERASE_RESET) {
    105     DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_RESET\n"));
    106   }
    107 
    108   if (CardStatus->SWITCH_ERROR) {
    109     DEBUG ((EFI_D_ERROR, "CardStatus: SWITCH_ERROR\n"));
    110   }
    111 
    112   if ((Status & 0xFCFFA080) != 0) {
    113     return EFI_DEVICE_ERROR;
    114   }
    115 
    116   return EFI_SUCCESS;
    117 }
    118 
    119 /**
    120   Send command by using Host IO protocol
    121 
    122   @param  This                  A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
    123   @param  CommandIndex          The command index to set the command index field of command register.
    124   @param  Argument              Command argument to set the argument field of command register.
    125   @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
    126   @param  Buffer                Contains the data read from / write to the device.
    127   @param  BufferSize            The size of the buffer.
    128   @param  ResponseType          RESPONSE_TYPE.
    129   @param  TimeOut               Time out value in 1 ms unit.
    130   @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
    131 
    132   @retval EFI_SUCCESS
    133   @retval EFI_INVALID_PARAMETER
    134   @retval EFI_UNSUPPORTED
    135   @retval EFI_DEVICE_ERROR
    136 
    137 **/
    138 EFI_STATUS
    139 SendCommand (
    140   IN   CARD_DATA                  *CardData,
    141   IN   UINT16                     CommandIndex,
    142   IN   UINT32                     Argument,
    143   IN   TRANSFER_TYPE              DataType,
    144   IN   UINT8                      *Buffer, OPTIONAL
    145   IN   UINT32                     BufferSize,
    146   IN   RESPONSE_TYPE              ResponseType,
    147   IN   UINT32                     TimeOut,
    148   OUT  UINT32                     *ResponseData
    149   )
    150 {
    151 
    152   EFI_STATUS    Status;
    153   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    154   SDHostIo = CardData->SDHostIo;
    155   if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
    156     CommandIndex |= AUTO_CMD12_ENABLE;
    157   }
    158 
    159   Status = SDHostIo->SendCommand (
    160                    SDHostIo,
    161                    CommandIndex,
    162                    Argument,
    163                    DataType,
    164                    Buffer,
    165                    BufferSize,
    166                    ResponseType,
    167                    TimeOut,
    168                    ResponseData
    169                    );
    170   if (!EFI_ERROR (Status)) {
    171     if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
    172       ASSERT(ResponseData != NULL);
    173       Status = CheckCardStatus (*ResponseData);
    174     }
    175   } else {
    176     SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
    177   }
    178 
    179   return Status;
    180 }
    181 
    182 /**
    183   Send the card APP_CMD command with the following command indicated by CommandIndex
    184 
    185   @param  CardData              Pointer to CARD_DATA.
    186   @param  CommandIndex          The command index to set the command index field of command register.
    187   @param  Argument              Command argument to set the argument field of command register.
    188   @param  DataType              TRANSFER_TYPE, indicates no data, data in or data out.
    189   @param  Buffer                Contains the data read from / write to the device.
    190   @param  BufferSize            The size of the buffer.
    191   @param  ResponseType          RESPONSE_TYPE.
    192   @param  TimeOut               Time out value in 1 ms unit.
    193   @param  ResponseData          Depending on the ResponseType, such as CSD or card status.
    194 
    195   @retval EFI_SUCCESS
    196   @retval EFI_INVALID_PARAMETER
    197   @retval EFI_UNSUPPORTED
    198   @retval EFI_DEVICE_ERROR
    199 
    200 **/
    201 EFI_STATUS
    202 SendAppCommand (
    203   IN   CARD_DATA                  *CardData,
    204   IN   UINT16                     CommandIndex,
    205   IN   UINT32                     Argument,
    206   IN   TRANSFER_TYPE              DataType,
    207   IN   UINT8                      *Buffer, OPTIONAL
    208   IN   UINT32                     BufferSize,
    209   IN   RESPONSE_TYPE              ResponseType,
    210   IN   UINT32                     TimeOut,
    211   OUT  UINT32                     *ResponseData
    212   )
    213 {
    214 
    215   EFI_STATUS                 Status;
    216   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    217   UINT8                      Index;
    218 
    219   SDHostIo = CardData->SDHostIo;
    220   Status = EFI_SUCCESS;
    221 
    222   for (Index = 0; Index < 2; Index++) {
    223     Status = SDHostIo->SendCommand (
    224                          SDHostIo,
    225                          APP_CMD,
    226                          (CardData->Address << 16),
    227                          NoData,
    228                          NULL,
    229                          0,
    230                          ResponseR1,
    231                          TIMEOUT_COMMAND,
    232                          (UINT32*)&(CardData->CardStatus)
    233                          );
    234     if (!EFI_ERROR (Status)) {
    235         Status = CheckCardStatus (*(UINT32*)&(CardData->CardStatus));
    236         if (CardData->CardStatus.SAPP_CMD != 1) {
    237           Status = EFI_DEVICE_ERROR;
    238         }
    239         if (!EFI_ERROR (Status)) {
    240            break;
    241         }
    242     } else {
    243        SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
    244     }
    245   }
    246 
    247   if (EFI_ERROR (Status)) {
    248     return Status;
    249   }
    250   if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
    251     CommandIndex |= AUTO_CMD12_ENABLE;
    252   }
    253 
    254   Status = SDHostIo->SendCommand (
    255                        SDHostIo,
    256                        CommandIndex,
    257                        Argument,
    258                        DataType,
    259                        Buffer,
    260                        BufferSize,
    261                        ResponseType,
    262                        TimeOut,
    263                        ResponseData
    264                        );
    265   if (!EFI_ERROR (Status)) {
    266     if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
    267       ASSERT(ResponseData != NULL);
    268       Status = CheckCardStatus (*ResponseData);
    269     }
    270   } else {
    271     SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
    272   }
    273 
    274   return Status;
    275 }
    276 
    277 
    278 /**
    279   Send the card FAST_IO command
    280 
    281   @param  CardData               Pointer to CARD_DATA.
    282   @param  RegisterAddress        Register Address.
    283   @param  RegisterData           Pointer to register Data.
    284   @param  Write                  TRUE for write, FALSE for read.
    285 
    286   @retval EFI_SUCCESS
    287   @retval EFI_UNSUPPORTED
    288   @retval EFI_INVALID_PARAMETER
    289   @retval EFI_DEVICE_ERROR
    290 
    291 **/
    292 EFI_STATUS
    293 FastIO (
    294   IN      CARD_DATA   *CardData,
    295   IN      UINT8       RegisterAddress,
    296   IN  OUT UINT8       *RegisterData,
    297   IN      BOOLEAN     Write
    298   )
    299 {
    300   EFI_STATUS                 Status;
    301   UINT32                     Argument;
    302   UINT32                     Data;
    303 
    304   Status   = EFI_SUCCESS;
    305 
    306   if (RegisterData == NULL) {
    307     Status = EFI_INVALID_PARAMETER;
    308     goto Exit;
    309   }
    310 
    311   Argument = (CardData->Address << 16) | (RegisterAddress << 8);
    312   if (Write) {
    313     Argument |= BIT15 | (*RegisterData);
    314   }
    315 
    316   Status = SendCommand (
    317              CardData,
    318              FAST_IO,
    319              Argument,
    320              NoData,
    321              NULL,
    322              0,
    323              ResponseR4,
    324              TIMEOUT_COMMAND,
    325              &Data
    326              );
    327   if (EFI_ERROR (Status)) {
    328     goto Exit;
    329   }
    330 
    331   if ((Data & BIT15) == 0) {
    332     Status = EFI_DEVICE_ERROR;
    333     goto Exit;
    334   }
    335 
    336   if (!Write) {
    337    *RegisterData = (UINT8)Data;
    338   }
    339 
    340 Exit:
    341   return Status;
    342 }
    343 
    344 /**
    345   Send the card GO_INACTIVE_STATE command.
    346 
    347   @param  CardData             Pointer to CARD_DATA.
    348 
    349   @return EFI_SUCCESS
    350   @return others
    351 
    352 **/
    353 EFI_STATUS
    354 PutCardInactive (
    355   IN  CARD_DATA   *CardData
    356   )
    357 {
    358   EFI_STATUS                 Status;
    359 
    360 
    361   Status = SendCommand (
    362              CardData,
    363              GO_INACTIVE_STATE,
    364              (CardData->Address << 16),
    365              NoData,
    366              NULL,
    367              0,
    368              ResponseNo,
    369              TIMEOUT_COMMAND,
    370              NULL
    371              );
    372 
    373   return Status;
    374 
    375 }
    376 
    377 /**
    378   Get card interested information for CSD rergister
    379 
    380   @param  CardData               Pointer to CARD_DATA.
    381 
    382   @retval EFI_SUCCESS
    383   @retval EFI_UNSUPPORTED
    384   @retval EFI_INVALID_PARAMETER
    385 
    386 **/
    387 EFI_STATUS
    388 CaculateCardParameter (
    389   IN  CARD_DATA    *CardData
    390   )
    391 {
    392   EFI_STATUS     Status;
    393   UINT32         Frequency;
    394   UINT32         Multiple;
    395   UINT32         CSize;
    396   CSD_SDV2       *CsdSDV2;
    397 
    398   Status = EFI_SUCCESS;
    399 
    400   switch (CardData->CSDRegister.TRAN_SPEED & 0x7) {
    401     case 0:
    402       Frequency = 100 * 1000;
    403       break;
    404 
    405     case 1:
    406       Frequency = 1 * 1000 * 1000;
    407       break;
    408 
    409     case 2:
    410       Frequency = 10 * 1000 * 1000;
    411       break;
    412 
    413     case 3:
    414       Frequency = 100 * 1000 * 1000;
    415       break;
    416 
    417     default:
    418       Status = EFI_INVALID_PARAMETER;
    419       goto Exit;
    420   }
    421 
    422   switch ((CardData->CSDRegister.TRAN_SPEED >> 3) & 0xF) {
    423     case 1:
    424       Multiple = 10;
    425       break;
    426 
    427     case 2:
    428       Multiple = 12;
    429       break;
    430 
    431     case 3:
    432       Multiple = 13;
    433       break;
    434 
    435     case 4:
    436       Multiple = 15;
    437       break;
    438 
    439     case 5:
    440       Multiple = 20;
    441       break;
    442 
    443     case 6:
    444       if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
    445         Multiple = 26;
    446       } else {
    447         Multiple = 25;
    448       }
    449       break;
    450 
    451     case 7:
    452       Multiple = 30;
    453       break;
    454 
    455     case 8:
    456       Multiple = 35;
    457       break;
    458 
    459     case 9:
    460       Multiple = 40;
    461       break;
    462 
    463     case 10:
    464       Multiple = 45;
    465       break;
    466 
    467     case 11:
    468       if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
    469         Multiple = 52;
    470       } else {
    471         Multiple = 50;
    472       }
    473       break;
    474 
    475     case 12:
    476       Multiple = 55;
    477       break;
    478 
    479     case 13:
    480       Multiple = 60;
    481       break;
    482 
    483     case 14:
    484       Multiple = 70;
    485       break;
    486 
    487     case 15:
    488       Multiple = 80;
    489       break;
    490 
    491     default:
    492       Status = EFI_INVALID_PARAMETER;
    493       goto Exit;
    494   }
    495 
    496   Frequency = Frequency * Multiple / 10;
    497   CardData->MaxFrequency = Frequency;
    498 
    499   CardData->BlockLen = 1 << CardData->CSDRegister.READ_BL_LEN;
    500 
    501   if (CardData->CardType == SDMemoryCard2High) {
    502     ASSERT(CardData->CSDRegister.CSD_STRUCTURE == 1);
    503     CsdSDV2 = (CSD_SDV2*)&CardData->CSDRegister;
    504     //
    505     // The SD Spec 2.0 says (CSize + 1) * 512K is the total size, so block numbber is (CSize + 1) * 1K
    506     // the K here means 1024 not 1000
    507     //
    508     CardData->BlockNumber = DivU64x32 (MultU64x32 (CsdSDV2->C_SIZE + 1, 512 * 1024) , CardData->BlockLen);
    509   } else {
    510     //
    511     // For MMC card > 2G, the block number will be recaculate later
    512     //
    513     CSize = CardData->CSDRegister.C_SIZELow2 | (CardData->CSDRegister.C_SIZEHigh10 << 2);
    514     CardData->BlockNumber = MultU64x32 (LShiftU64 (1, CardData->CSDRegister.C_SIZE_MULT + 2), CSize + 1);
    515   }
    516 
    517   //
    518   //For >= 2G card, BlockLen may be 1024, but the transfer size is still 512 bytes
    519   //
    520   if (CardData->BlockLen > 512) {
    521     CardData->BlockNumber = DivU64x32 (MultU64x32 (CardData->BlockNumber, CardData->BlockLen), 512);
    522     CardData->BlockLen    = 512;
    523   }
    524 
    525   DEBUG((
    526     EFI_D_INFO,
    527           "CalculateCardParameter: Card Size: 0x%lx\n", MultU64x32 (CardData->BlockNumber, CardData->BlockLen)
    528     ));
    529 
    530 Exit:
    531   return Status;
    532 }
    533 
    534 /**
    535   Test the bus width setting for MMC card.It is used only for verification purpose.
    536 
    537   @param  CardData               Pointer to CARD_DATA.
    538   @param  Width                  1, 4, 8 bits.
    539 
    540   @retval EFI_SUCCESS
    541   @retval EFI_UNSUPPORTED
    542   @retval EFI_INVALID_PARAMETER
    543 
    544 **/
    545 EFI_STATUS
    546 MMCCardBusWidthTest (
    547   IN  CARD_DATA             *CardData,
    548   IN  UINT32                Width
    549   )
    550 {
    551   EFI_STATUS                 Status;
    552   UINT64                     Data;
    553   UINT64                     Value;
    554 
    555   ASSERT(CardData != NULL);
    556 
    557 
    558   Value = 0;
    559 
    560   switch (Width) {
    561     case 1:
    562       Data = 0x80;
    563       break;
    564 
    565     case 4:
    566       Data = 0x5A;
    567       break;
    568 
    569     case 8:
    570       Data = 0xAA55;
    571       break;
    572 
    573     default:
    574       Status = EFI_INVALID_PARAMETER;
    575       goto Exit;
    576   }
    577 
    578   CopyMem (CardData->AlignedBuffer, &Data, Width);
    579   Status  = SendCommand (
    580               CardData,
    581               BUSTEST_W,
    582               0,
    583               OutData,
    584               CardData->AlignedBuffer,
    585               Width,
    586               ResponseR1,
    587               TIMEOUT_COMMAND,
    588               (UINT32*)&(CardData->CardStatus)
    589               );
    590   if (EFI_ERROR (Status)) {
    591     DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_W 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
    592     goto Exit;
    593   }
    594 
    595   gBS->Stall (10 * 1000);
    596 
    597   Data = 0;
    598 
    599   Status  = SendCommand (
    600               CardData,
    601               BUSTEST_R,
    602               0,
    603               InData,
    604               CardData->AlignedBuffer,
    605               Width,
    606               ResponseR1,
    607               TIMEOUT_COMMAND,
    608               (UINT32*)&(CardData->CardStatus)
    609               );
    610   if (EFI_ERROR (Status)) {
    611     DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_R 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
    612     goto Exit;
    613   }
    614   CopyMem (&Data, CardData->AlignedBuffer, Width);
    615 
    616   switch (Width) {
    617     case 1:
    618       Value = (~(Data ^ 0x80)) & 0xC0;
    619       break;
    620     case 4:
    621       Value = (~(Data ^ 0x5A)) & 0xFF;
    622       break;
    623     case 8:
    624       Value = (~(Data ^ 0xAA55)) & 0xFFFF;
    625       break;
    626   }
    627 
    628   if (Value == 0) {
    629     Status = EFI_SUCCESS;
    630   } else {
    631     Status = EFI_UNSUPPORTED;
    632   }
    633 
    634 
    635 Exit:
    636   return Status;
    637 }
    638 
    639 /**
    640   This function can detect these card types:
    641     1. MMC card
    642     2. SD 1.1 card
    643     3. SD 2.0 standard card
    644     3. SD 2.0 high capacity card
    645 
    646   @param  CardData             Pointer to CARD_DATA.
    647 
    648   @return EFI_SUCCESS
    649   @return others
    650 
    651 **/
    652 EFI_STATUS
    653 GetCardType (
    654   IN  CARD_DATA              *CardData
    655   )
    656 {
    657   EFI_STATUS                 Status;
    658   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    659   UINT32                     Argument;
    660   UINT32                     ResponseData;
    661   UINT32                     Count;
    662   BOOLEAN                    SDCommand8Support;
    663 
    664 
    665   SDHostIo = CardData->SDHostIo;
    666 
    667   //
    668   // Reset the card
    669   //
    670   Status  = SendCommand (
    671               CardData,
    672               GO_IDLE_STATE,
    673               0,
    674               NoData,
    675               NULL,
    676               0,
    677               ResponseNo,
    678               TIMEOUT_COMMAND,
    679               NULL
    680               );
    681   if (EFI_ERROR (Status)) {
    682     DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
    683     goto Exit;
    684   }
    685 
    686   //
    687   //No spec requirment, can be adjusted
    688   //
    689   gBS->Stall (10 * 1000);
    690 
    691 
    692   //
    693   // Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass
    694   // MMC and SD1.1 card will fail this command
    695   //
    696   Argument          = (VOLTAGE_27_36 << 8) | CHECK_PATTERN;
    697   ResponseData      = 0;
    698   SDCommand8Support = FALSE;
    699 
    700   Status  = SendCommand (
    701               CardData,
    702               SEND_IF_COND,
    703               Argument,
    704               NoData,
    705               NULL,
    706               0,
    707               ResponseR7,
    708               TIMEOUT_COMMAND,
    709               &ResponseData
    710               );
    711 
    712   if (EFI_ERROR (Status)) {
    713     if (Status != EFI_TIMEOUT) {
    714        DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, none time out error\n"));
    715        goto Exit;
    716     }
    717   } else {
    718      if (ResponseData != Argument) {
    719        DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, respond data does not match send data\n"));
    720        Status = EFI_DEVICE_ERROR;
    721        goto Exit;
    722     }
    723     SDCommand8Support = TRUE;
    724   }
    725 
    726 
    727   Argument = 0;
    728   if (SDHostIo->HostCapability.V30Support == TRUE) {
    729     Argument |= BIT17 | BIT18;
    730   } else if (SDHostIo->HostCapability.V33Support == TRUE) {
    731     Argument |= BIT20 | BIT21;
    732   }
    733 
    734   if (SDCommand8Support) {
    735     //
    736     //If command SD_SEND_OP_COND sucessed, it should be set.
    737     // SD 1.1 card will ignore it
    738     // SD 2.0 standard card will repsond with CCS 0, SD high capacity card will respond with CCS 1
    739     // CCS is BIT30 of OCR
    740     Argument |= BIT30;
    741   }
    742 
    743 
    744   Count        = 20;
    745   //
    746   //Only SD card will respond to this command, and spec says the card only checks condition at first ACMD41 command
    747   //
    748   do {
    749     Status  = SendAppCommand (
    750                 CardData,
    751                 SD_SEND_OP_COND,
    752                 Argument,
    753                 NoData,
    754                 NULL,
    755                 0,
    756                 ResponseR3,
    757                 TIMEOUT_COMMAND,
    758                 (UINT32*)&(CardData->OCRRegister)
    759                 );
    760     if (EFI_ERROR (Status)) {
    761       if ((Status == EFI_TIMEOUT) && (!SDCommand8Support)) {
    762         CardData->CardType = MMCCard;
    763         Status = EFI_SUCCESS;
    764         DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, MMC card was identified\n"));
    765       } else {
    766         //
    767         // Not as expected, MMC card should has no response, which means timeout.
    768         // SD card should pass this command
    769         //
    770         DEBUG((EFI_D_ERROR, "SD_SEND_OP_COND Fail, check whether it is neither a MMC card nor a SD card\n"));
    771       }
    772       goto Exit;
    773     }
    774     //
    775     //Avoid waiting if sucess. Busy bit 0 means not ready
    776     //
    777     if (CardData->OCRRegister.Busy == 1) {
    778       break;
    779     }
    780 
    781     gBS->Stall (50 * 1000);
    782     Count--;
    783     if (Count == 0) {
    784       DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
    785       Status = EFI_TIMEOUT;
    786       goto Exit;
    787     }
    788   } while (1);
    789 
    790   //
    791   //Check supported voltage
    792   //
    793   Argument = 0;
    794   if (SDHostIo->HostCapability.V30Support == TRUE) {
    795     if ((CardData->OCRRegister.V270_V360 & BIT2) == BIT2) {
    796       Argument |= BIT17;
    797     } else if ((CardData->OCRRegister.V270_V360 & BIT3) == BIT3) {
    798       Argument |= BIT18;
    799     }
    800   } else if (SDHostIo->HostCapability.V33Support == TRUE) {
    801      if ((CardData->OCRRegister.V270_V360 & BIT5) == BIT5) {
    802        Argument |= BIT20;
    803      } else if ((CardData->OCRRegister.V270_V360 & BIT6) == BIT6) {
    804        Argument |= BIT21;
    805      }
    806   }
    807 
    808   if (Argument == 0) {
    809      //
    810      //No matched support voltage
    811      //
    812      PutCardInactive (CardData);
    813      DEBUG((EFI_D_ERROR, "No matched voltage for this card\n"));
    814      Status = EFI_UNSUPPORTED;
    815      goto Exit;
    816   }
    817 
    818   CardData->CardType = SDMemoryCard;
    819   if (SDCommand8Support == TRUE) {
    820    CardData->CardType = SDMemoryCard2;
    821    DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above standard card was identified\n"));
    822   }
    823 
    824   if ((CardData->OCRRegister.AccessMode & BIT1) == BIT1) {
    825     CardData->CardType = SDMemoryCard2High;
    826     DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above high capacity card was identified\n"));
    827   }
    828 
    829 
    830 
    831 Exit:
    832   return Status;
    833 }
    834 
    835 /**
    836   MMC card high/low voltage selection function
    837 
    838   @param  CardData               Pointer to CARD_DATA.
    839 
    840   @retval EFI_SUCCESS
    841   @retval EFI_INVALID_PARAMETER
    842   @retval EFI_UNSUPPORTED
    843   @retval EFI_BAD_BUFFER_SIZE
    844 
    845 **/
    846 EFI_STATUS
    847 MMCCardVoltageSelection (
    848   IN  CARD_DATA              *CardData
    849   )
    850 {
    851   EFI_STATUS                 Status;
    852   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    853   UINT8                      Retry;
    854   UINT32                     TimeOut;
    855 
    856   Status   = EFI_SUCCESS;
    857   SDHostIo = CardData->SDHostIo;
    858   //
    859   //First try the high voltage, then if supported choose the low voltage
    860   //
    861 
    862     for (Retry = 0; Retry < 3; Retry++) {
    863       //
    864       // To bring back the normal MMC card to work
    865       // after sending the SD command. Otherwise some
    866       // card could not work
    867 
    868       Status  = SendCommand (
    869                 CardData,
    870                   GO_IDLE_STATE,
    871                   0,
    872                   NoData,
    873                   NULL,
    874                   0,
    875                   ResponseNo,
    876                   TIMEOUT_COMMAND,
    877                   NULL
    878                   );
    879       if (EFI_ERROR (Status)) {
    880         DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
    881         continue;
    882       }
    883       //
    884       //CE-ATA device needs long delay
    885       //
    886       gBS->Stall ((Retry + 1) * 50 * 1000);
    887 
    888       //
    889       //Get OCR register to check voltage support, first time the OCR is 0
    890       //
    891       Status  = SendCommand (
    892                 CardData,
    893                   SEND_OP_COND,
    894                   0,
    895                   NoData,
    896                   NULL,
    897                   0,
    898                   ResponseR3,
    899                   TIMEOUT_COMMAND,
    900                   (UINT32*)&(CardData->OCRRegister)
    901                   );
    902       if (!EFI_ERROR (Status)) {
    903         break;
    904       }
    905     }
    906 
    907     if (Retry == 3) {
    908       DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
    909       Status = EFI_DEVICE_ERROR;
    910       goto Exit;
    911     }
    912 
    913     //
    914     //TimeOut Value, 5000 * 100 * 1000 = 5 s
    915     //
    916     TimeOut = 5000;
    917 
    918     do {
    919       Status  = SendCommand (
    920                 CardData,
    921                   SEND_OP_COND,
    922                   0x40300000,
    923                   NoData,
    924                   NULL,
    925                   0,
    926                   ResponseR3,
    927                   TIMEOUT_COMMAND,
    928                   (UINT32*)&(CardData->OCRRegister)
    929                   );
    930       if (EFI_ERROR (Status)) {
    931         DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
    932         goto Exit;
    933       }
    934 
    935       gBS->Stall (1 * 1000);
    936       TimeOut--;
    937       if (TimeOut == 0) {
    938         Status = EFI_TIMEOUT;
    939       DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
    940         goto Exit;
    941       }
    942     } while (CardData->OCRRegister.Busy != 1);
    943 
    944   if (CardData->OCRRegister.AccessMode == 2) // eMMC Card uses Sector Addressing - High Capacity
    945     {
    946     DEBUG((EFI_D_INFO, "eMMC Card is High Capacity\n"));
    947     CardData->CardType = MMCCardHighCap;
    948   }
    949 
    950 Exit:
    951   return Status;
    952 
    953 }
    954 
    955 /**
    956   This function set the bus and device width for MMC card
    957 
    958   @param  CardData               Pointer to CARD_DATA.
    959   @param  Width                  1, 4, 8 bits.
    960 
    961   @retval EFI_SUCCESS
    962   @retval EFI_UNSUPPORTED
    963   @retval EFI_INVALID_PARAMETER
    964 
    965 **/
    966 EFI_STATUS
    967 MMCCardSetBusWidth (
    968   IN  CARD_DATA              *CardData,
    969   IN  UINT8                  BusWidth,
    970   IN  BOOLEAN                EnableDDRMode
    971   )
    972 {
    973   EFI_STATUS                 Status;
    974   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    975   SWITCH_ARGUMENT            SwitchArgument;
    976   UINT8                      Value;
    977 
    978   SDHostIo = CardData->SDHostIo;
    979   Value = 0;
    980   switch (BusWidth) {
    981     case 8:
    982       if (EnableDDRMode)
    983         Value = 6;
    984       else
    985       Value = 2;
    986       break;
    987 
    988     case 4:
    989       if (EnableDDRMode)
    990         Value = 5;
    991       else
    992       Value = 1;
    993       break;
    994 
    995     case 1:
    996       if (EnableDDRMode)    // Bus width 1 is not supported in ddr mode
    997         return EFI_UNSUPPORTED;
    998       Value = 0;
    999       break;
   1000 
   1001     default:
   1002      ASSERT(0);
   1003   }
   1004 
   1005 
   1006   ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1007   SwitchArgument.CmdSet = 0;
   1008   SwitchArgument.Value  = Value;
   1009   SwitchArgument.Index  = (UINT32)((UINTN)
   1010   (&(CardData->ExtCSDRegister.BUS_WIDTH)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1011   SwitchArgument.Access = WriteByte_Mode;
   1012   Status  = SendCommand (
   1013               CardData,
   1014               SWITCH,
   1015               *(UINT32*)&SwitchArgument,
   1016               NoData,
   1017               NULL,
   1018               0,
   1019               ResponseR1b,
   1020               TIMEOUT_COMMAND,
   1021               (UINT32*)&(CardData->CardStatus)
   1022               );
   1023   if (!EFI_ERROR (Status)) {
   1024      Status  = SendCommand (
   1025                  CardData,
   1026                  SEND_STATUS,
   1027                  (CardData->Address << 16),
   1028                  NoData,
   1029                  NULL,
   1030                  0,
   1031                  ResponseR1,
   1032                  TIMEOUT_COMMAND,
   1033                  (UINT32*)&(CardData->CardStatus)
   1034                  );
   1035     if (EFI_ERROR (Status)) {
   1036       DEBUG((EFI_D_ERROR, "SWITCH %d bits Fail\n", BusWidth));
   1037       goto Exit;
   1038     } else {
   1039       DEBUG((EFI_D_ERROR, "MMCCardSetBusWidth:SWITCH Card Status:0x%x\n", *(UINT32*)&(CardData->CardStatus)));
   1040       Status = SDHostIo->SetBusWidth (SDHostIo, BusWidth);
   1041       if (EFI_ERROR (Status)) {
   1042          DEBUG((EFI_D_ERROR, "SWITCH set %d bits Fail\n", BusWidth));
   1043          goto Exit;
   1044       }
   1045       gBS->Stall (5 * 1000);
   1046     }
   1047   }
   1048 
   1049   if (!EnableDDRMode) {     // CMD19 and CMD14 are illegal commands in ddr mode
   1050   //if (EFI_ERROR (Status)) {
   1051   //  DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest: Fail to enable high speed mode\n"));
   1052   //  goto Exit;
   1053   //}
   1054 
   1055   Status = MMCCardBusWidthTest (CardData, BusWidth);
   1056   if (EFI_ERROR (Status)) {
   1057     DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest %d bit Fail\n", BusWidth));
   1058     goto Exit;
   1059     }
   1060   }
   1061 
   1062   CardData->CurrentBusWidth = BusWidth;
   1063 
   1064 Exit:
   1065   return Status;
   1066 }
   1067 
   1068 
   1069 /**
   1070   MMC/SD card init function
   1071 
   1072   @param  CardData             Pointer to CARD_DATA.
   1073 
   1074   @return EFI_SUCCESS
   1075   @return others
   1076 
   1077 **/
   1078 EFI_STATUS
   1079 MMCSDCardInit (
   1080   IN  CARD_DATA              *CardData
   1081   )
   1082 {
   1083   EFI_STATUS                 Status;
   1084   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
   1085   SWITCH_ARGUMENT            SwitchArgument;
   1086   UINT32                     Data;
   1087   UINT32                     Argument;
   1088   UINT32                     nIndex;
   1089   UINT8                      PowerValue;
   1090   BOOLEAN                    EnableDDRMode;
   1091 
   1092   ASSERT(CardData != NULL);
   1093   SDHostIo                  = CardData->SDHostIo;
   1094   EnableDDRMode             = FALSE;
   1095 
   1096   CardData->CardType = UnknownCard;
   1097   Status = GetCardType (CardData);
   1098   if (EFI_ERROR (Status)) {
   1099     goto Exit;
   1100   }
   1101   DEBUG((DEBUG_INFO, "CardData->CardType  0x%x\n", CardData->CardType));
   1102 
   1103   ASSERT (CardData->CardType != UnknownCard);
   1104   //
   1105   //MMC, SD card need host auto stop command support
   1106   //
   1107   SDHostIo->EnableAutoStopCmd (SDHostIo, TRUE);
   1108 
   1109   if (CardData->CardType == MMCCard) {
   1110     Status = MMCCardVoltageSelection (CardData);
   1111     if (EFI_ERROR(Status)) {
   1112       goto Exit;
   1113     }
   1114   }
   1115 
   1116   //
   1117   // Get CID Register
   1118   //
   1119   Status  = SendCommand (
   1120               CardData,
   1121               ALL_SEND_CID,
   1122               0,
   1123               NoData,
   1124               NULL,
   1125               0,
   1126               ResponseR2,
   1127               TIMEOUT_COMMAND,
   1128               (UINT32*)&(CardData->CIDRegister)
   1129               );
   1130   if (EFI_ERROR (Status)) {
   1131     DEBUG((EFI_D_ERROR, "ALL_SEND_CID Fail Status = 0x%x\n", Status));
   1132     goto Exit;
   1133   } else {
   1134     // Dump out the Card ID data
   1135     DEBUG((EFI_D_INFO, "Product Name: "));
   1136     for ( nIndex=0; nIndex<6; nIndex++ ) {
   1137       DEBUG((EFI_D_INFO, "%c", CardData->CIDRegister.PNM[nIndex]));
   1138     }
   1139     DEBUG((EFI_D_INFO, "\nApplication ID : %d\n", CardData->CIDRegister.OID));
   1140     DEBUG((EFI_D_INFO, "Manufacturer ID: %d\n", CardData->CIDRegister.MID));
   1141     DEBUG((EFI_D_INFO, "Revision ID    : %d\n", CardData->CIDRegister.PRV));
   1142     DEBUG((EFI_D_INFO, "Serial Number  : %d\n", CardData->CIDRegister.PSN));
   1143   }
   1144 
   1145   //
   1146   //SET_RELATIVE_ADDR
   1147   //
   1148   if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
   1149     //
   1150     //Hard code the RCA address
   1151     //
   1152     CardData->Address = 1;
   1153 
   1154     //
   1155     // Set RCA Register
   1156     //
   1157     Status  = SendCommand (
   1158                 CardData,
   1159                 SET_RELATIVE_ADDR,
   1160                 (CardData->Address << 16),
   1161                 NoData,
   1162                 NULL,
   1163                 0,
   1164                 ResponseR1,
   1165                 TIMEOUT_COMMAND,
   1166                 (UINT32*)&(CardData->CardStatus)
   1167                 );
   1168     if (EFI_ERROR (Status)) {
   1169       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1170       goto Exit;
   1171     }
   1172   } else {
   1173     Data = 0;
   1174     Status  = SendCommand (
   1175                 CardData,
   1176                 SET_RELATIVE_ADDR,
   1177                 0,
   1178                 NoData,
   1179                 NULL,
   1180                 0,
   1181                 ResponseR6,
   1182                 TIMEOUT_COMMAND,
   1183                 &Data
   1184                 );
   1185     if (EFI_ERROR (Status)) {
   1186       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1187       goto Exit;
   1188     }
   1189 
   1190     CardData->Address = (UINT16)(Data >> 16);
   1191     *(UINT32*)&CardData->CardStatus      = Data & 0x1FFF;
   1192     CardData->CardStatus.ERROR           = (Data >> 13) & 0x1;
   1193     CardData->CardStatus.ILLEGAL_COMMAND = (Data >> 14) & 0x1;
   1194     CardData->CardStatus.COM_CRC_ERROR   = (Data >> 15) & 0x1;
   1195     Status = CheckCardStatus (*(UINT32*)&CardData->CardStatus);
   1196     if (EFI_ERROR (Status)) {
   1197       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1198       goto Exit;
   1199     }
   1200   }
   1201 
   1202   //
   1203   // Get CSD Register
   1204   //
   1205   Status  = SendCommand (
   1206               CardData,
   1207               SEND_CSD,
   1208               (CardData->Address << 16),
   1209               NoData,
   1210               NULL,
   1211               0,
   1212               ResponseR2,
   1213               TIMEOUT_COMMAND,
   1214               (UINT32*)&(CardData->CSDRegister)
   1215               );
   1216   if (EFI_ERROR (Status)) {
   1217     DEBUG((EFI_D_ERROR, "SEND_CSD Fail Status = 0x%x\n", Status));
   1218     goto Exit;
   1219   }
   1220 
   1221   DEBUG((EFI_D_INFO, "CardData->CSDRegister.SPEC_VERS = 0x%x\n", CardData->CSDRegister.SPEC_VERS));
   1222   DEBUG((EFI_D_INFO, "CardData->CSDRegister.CSD_STRUCTURE = 0x%x\n", CardData->CSDRegister.CSD_STRUCTURE));
   1223 
   1224   Status = CaculateCardParameter (CardData);
   1225   if (EFI_ERROR (Status)) {
   1226     goto Exit;
   1227   }
   1228 
   1229 
   1230   //
   1231   // It is platform and hardware specific, need hadrware engineer input
   1232   //
   1233   if (CardData->CSDRegister.DSR_IMP == 1) {
   1234     //
   1235     // Default is 0x404
   1236     //
   1237     Status  = SendCommand (
   1238                 CardData,
   1239                 SET_DSR,
   1240                 (DEFAULT_DSR_VALUE << 16),
   1241                 NoData,
   1242                 NULL,
   1243                 0,
   1244                 ResponseNo,
   1245                 TIMEOUT_COMMAND,
   1246                 NULL
   1247                 );
   1248     if (EFI_ERROR (Status)) {
   1249       DEBUG((EFI_D_ERROR, "SET_DSR Fail Status = 0x%x\n", Status));
   1250       //
   1251       // Assume can operate even fail
   1252       //
   1253     }
   1254   }
   1255   //
   1256   //Change clock frequency from 400KHz to max supported when not in high speed mode
   1257   //
   1258   Status = SDHostIo->SetClockFrequency (SDHostIo, CardData->MaxFrequency);
   1259   if (EFI_ERROR (Status)) {
   1260   DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
   1261   goto Exit;
   1262   }
   1263 
   1264   //
   1265   //Put the card into tran state
   1266   //
   1267   Status = SendCommand (
   1268              CardData,
   1269              SELECT_DESELECT_CARD,
   1270              (CardData->Address << 16),
   1271              NoData,
   1272              NULL,
   1273              0,
   1274              ResponseR1,
   1275              TIMEOUT_COMMAND,
   1276              (UINT32*)&(CardData->CardStatus)
   1277              );
   1278   if (EFI_ERROR (Status)) {
   1279     DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD Fail Status = 0x%x\n", Status));
   1280     goto Exit;
   1281   }
   1282 
   1283   //
   1284   // No spec requirment, can be adjusted
   1285   //
   1286   gBS->Stall (5 * 1000);
   1287   //
   1288   // No need to do so
   1289   //
   1290   //
   1291   Status  = SendCommand (
   1292               CardData,
   1293               SEND_STATUS,
   1294               (CardData->Address << 16),
   1295               NoData,
   1296               NULL,
   1297               0,
   1298               ResponseR1,
   1299               TIMEOUT_COMMAND,
   1300               (UINT32*)&(CardData->CardStatus)
   1301               );
   1302   if (EFI_ERROR (Status)) {
   1303      DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD SEND_STATUS Fail Status = 0x%x\n", Status));
   1304      goto Exit;
   1305   }
   1306   //
   1307   //if the SPEC_VERS indicates a version 4.0 or higher
   1308   //The card is a high speed card and support Switch
   1309   //and Send_ext_csd command
   1310   //otherwise it is an old card
   1311   //
   1312 
   1313   if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
   1314     //
   1315     //Only V4.0 and above supports more than 1 bits and high speed
   1316     //
   1317     if (CardData->CSDRegister.SPEC_VERS >= 4) {
   1318     //
   1319       //Get ExtCSDRegister
   1320       //
   1321       Status  = SendCommand (
   1322                   CardData,
   1323                   SEND_EXT_CSD,
   1324                   0x0,
   1325                   InData,
   1326                   CardData->AlignedBuffer,
   1327                   sizeof (EXT_CSD),
   1328                   ResponseR1,
   1329                   TIMEOUT_DATA,
   1330                   (UINT32*)&(CardData->CardStatus)
   1331                   );
   1332       if (EFI_ERROR (Status)) {
   1333         DEBUG((EFI_D_ERROR, "SEND_EXT_CSD Fail Status = 0x%x\n", Status));
   1334         goto Exit;
   1335       }
   1336 
   1337       CopyMem (&(CardData->ExtCSDRegister), CardData->AlignedBuffer, sizeof (EXT_CSD));
   1338 
   1339       //
   1340       // Recaculate the block number for >2G MMC card
   1341       //
   1342       Data  = (CardData->ExtCSDRegister.SEC_COUNT[0]) |
   1343               (CardData->ExtCSDRegister.SEC_COUNT[1] << 8) |
   1344               (CardData->ExtCSDRegister.SEC_COUNT[2] << 16) |
   1345               (CardData->ExtCSDRegister.SEC_COUNT[3] << 24);
   1346 
   1347       if (Data != 0) {
   1348         CardData->BlockNumber = Data;
   1349       }
   1350       DEBUG((DEBUG_INFO, "CardData->BlockNumber  %d\n", Data));
   1351       DEBUG((EFI_D_ERROR, "CardData->ExtCSDRegister.CARD_TYPE -> %d\n", (UINTN)CardData->ExtCSDRegister.CARD_TYPE));
   1352       if ((CardData->ExtCSDRegister.CARD_TYPE & BIT2)||
   1353           (CardData->ExtCSDRegister.CARD_TYPE & BIT3)) {
   1354           //DEBUG((DEBUG_INFO, "To enable DDR mode\n"));
   1355           //EnableDDRMode = TRUE;
   1356       }
   1357       //
   1358       // Check current chipset capability and the plugged-in card
   1359       // whether supports HighSpeed
   1360       //
   1361       if (SDHostIo->HostCapability.HighSpeedSupport) {
   1362 
   1363         //
   1364         //Change card timing to high speed interface timing
   1365         //
   1366         ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1367         SwitchArgument.CmdSet = 0;
   1368         SwitchArgument.Value  = 1;
   1369         SwitchArgument.Index  = (UINT32)((UINTN)
   1370         (&(CardData->ExtCSDRegister.HS_TIMING)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1371         SwitchArgument.Access = WriteByte_Mode;
   1372         Status  = SendCommand (
   1373                     CardData,
   1374                     SWITCH,
   1375                     *(UINT32*)&SwitchArgument,
   1376                     NoData,
   1377                     NULL,
   1378                     0,
   1379                     ResponseR1b,
   1380                     TIMEOUT_COMMAND,
   1381                     (UINT32*)&(CardData->CardStatus)
   1382                     );
   1383         if (EFI_ERROR (Status)) {
   1384           DEBUG((EFI_D_ERROR, "MMCSDCardInit:SWITCH frequency Fail Status = 0x%x\n", Status));
   1385         }
   1386 
   1387         gBS->Stall (5 * 1000);
   1388 
   1389 
   1390         if (!EFI_ERROR (Status)) {
   1391           Status  = SendCommand (
   1392                       CardData,
   1393                       SEND_STATUS,
   1394                       (CardData->Address << 16),
   1395                       NoData,
   1396                       NULL,
   1397                       0,
   1398                       ResponseR1,
   1399                       TIMEOUT_COMMAND,
   1400                       (UINT32*)&(CardData->CardStatus)
   1401                       );
   1402           if (!EFI_ERROR (Status)) {
   1403             if (EnableDDRMode) {
   1404               DEBUG((EFI_D_ERROR, "Enable ddr mode on host controller\n"));
   1405               SDHostIo->SetDDRMode (SDHostIo, TRUE);
   1406             } else  {
   1407               DEBUG((EFI_D_ERROR, "Enable high speed mode on host controller\n"));
   1408               SDHostIo->SetHighSpeedMode (SDHostIo, TRUE);
   1409             }
   1410           //
   1411           // Change host clock to support high speed and enable chispet to
   1412           // support speed
   1413           //
   1414             if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1415               Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP_HIGH);
   1416             } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1417               Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP);
   1418             } else {
   1419               Status = EFI_UNSUPPORTED;
   1420             }
   1421             if (EFI_ERROR (Status)) {
   1422               DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
   1423               goto Exit;
   1424             }
   1425             //
   1426             // It seems no need to stall after changing bus freqeuncy.
   1427             // It is said that the freqeuncy can be changed at any time. Just appends 8 clocks after command.
   1428             // But SetClock alreay has delay.
   1429             //
   1430           }
   1431         }
   1432 
   1433       }
   1434 
   1435 
   1436 
   1437       //
   1438       // Prefer wide bus width for performance
   1439       //
   1440       //
   1441       // Set to BusWidth bits mode, only version 4.0 or above support more than 1 bits
   1442       //
   1443       if (SDHostIo->HostCapability.BusWidth8 == TRUE) {
   1444          Status = MMCCardSetBusWidth (CardData, 8, EnableDDRMode);
   1445          if (EFI_ERROR (Status)) {
   1446             //
   1447             // CE-ATA may support 8 bits and 4 bits, but has no software method for detection
   1448             //
   1449             Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
   1450             if (EFI_ERROR (Status)) {
   1451               goto Exit;
   1452             }
   1453          }
   1454       } else if (SDHostIo->HostCapability.BusWidth4 == TRUE) {
   1455          Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
   1456          if (EFI_ERROR (Status)) {
   1457            goto Exit;
   1458          }
   1459       }
   1460 
   1461       PowerValue = 0;
   1462 
   1463       if (CardData->CurrentBusWidth == 8) {
   1464         if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1465           PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
   1466           PowerValue = PowerValue >> 4;
   1467         } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1468           PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
   1469           PowerValue = PowerValue >> 4;
   1470         }
   1471       } else if (CardData->CurrentBusWidth == 4) {
   1472          if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1473           PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
   1474           PowerValue = PowerValue & 0xF;
   1475          } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1476            PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
   1477            PowerValue = PowerValue & 0xF;
   1478          }
   1479       }
   1480 
   1481       if (PowerValue != 0) {
   1482         //
   1483         //Update Power Class
   1484         //
   1485         ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1486         SwitchArgument.CmdSet = 0;
   1487         SwitchArgument.Value  = PowerValue;
   1488         SwitchArgument.Index  = (UINT32)((UINTN)
   1489         (&(CardData->ExtCSDRegister.POWER_CLASS)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1490         SwitchArgument.Access = WriteByte_Mode;
   1491         Status  = SendCommand (
   1492                     CardData,
   1493                     SWITCH,
   1494                     *(UINT32*)&SwitchArgument,
   1495                     NoData,
   1496                     NULL,
   1497                     0,
   1498                     ResponseR1b,
   1499                     TIMEOUT_COMMAND,
   1500                     (UINT32*)&(CardData->CardStatus)
   1501                     );
   1502          if (!EFI_ERROR (Status)) {
   1503            Status  = SendCommand (
   1504                        CardData,
   1505                        SEND_STATUS,
   1506                        (CardData->Address << 16),
   1507                        NoData,
   1508                        NULL,
   1509                        0,
   1510                        ResponseR1,
   1511                        TIMEOUT_COMMAND,
   1512                        (UINT32*)&(CardData->CardStatus)
   1513                        );
   1514            if (EFI_ERROR (Status)) {
   1515              DEBUG((EFI_D_ERROR, "SWITCH Power Class Fail Status = 0x%x\n", Status));
   1516            }
   1517            //gBS->Stall (10 * 1000);
   1518          }
   1519       }
   1520 
   1521 
   1522 
   1523     } else {
   1524 
   1525 
   1526       DEBUG((EFI_D_ERROR, "MMC Card version %d only supportes 1 bits at lower transfer speed\n",CardData->CSDRegister.SPEC_VERS));
   1527     }
   1528   } else {
   1529       //
   1530       // Pin 1, at power up this line has a 50KOhm pull up enabled in the card.
   1531       // This pull-up should be disconnected by the user, during regular data transfer,
   1532       // with SET_CLR_CARD_DETECT (ACMD42) command
   1533       //
   1534       Status  = SendAppCommand (
   1535                   CardData,
   1536                   SET_CLR_CARD_DETECT,
   1537                   0,
   1538                   NoData,
   1539                   NULL,
   1540                   0,
   1541                   ResponseR1,
   1542                   TIMEOUT_COMMAND,
   1543                   (UINT32*)&(CardData->CardStatus)
   1544                   );
   1545       if (EFI_ERROR (Status)) {
   1546         DEBUG((EFI_D_ERROR, "SET_CLR_CARD_DETECT Fail Status = 0x%x\n", Status));
   1547         goto Exit;
   1548       }
   1549 
   1550       /*
   1551       //
   1552       // Don't rely on SCR and SD status, some cards have unexpected SCR.
   1553       // It only sets private section, the other bits are 0
   1554       // such as Sandisk Ultra II 4.0G, KinSton mini SD 128M, Toshiba 2.0GB
   1555       // Some card even fail this command, KinSton SD 4GB
   1556       //
   1557       Status  = SendAppCommand (
   1558                   CardData,
   1559                   SEND_SCR,
   1560                   0,
   1561                   InData,
   1562                   (UINT8*)&(CardData->SCRRegister),
   1563                   sizeof(SCR),
   1564                   ResponseR1,
   1565                   TIMEOUT_COMMAND,
   1566                   (UINT32*)&(CardData->CardStatus)
   1567                   );
   1568       if (EFI_ERROR (Status)) {
   1569         goto Exit;
   1570       }
   1571 
   1572       //
   1573       // SD memory card at least supports 1 and 4 bits.
   1574       //
   1575       // ASSERT ((CardData->SCRRegister.SD_BUS_WIDTH & (BIT0 | BIT2)) == (BIT0 | BIT2));
   1576       */
   1577 
   1578       //
   1579       // Set Bus Width to 4
   1580       //
   1581       Status  = SendAppCommand (
   1582                   CardData,
   1583                   SET_BUS_WIDTH,
   1584                   SD_BUS_WIDTH_4,
   1585                   NoData,
   1586                   NULL,
   1587                   0,
   1588                   ResponseR1,
   1589                   TIMEOUT_COMMAND,
   1590                   (UINT32*)&(CardData->CardStatus)
   1591                   );
   1592       if (EFI_ERROR (Status)) {
   1593         DEBUG((EFI_D_ERROR, "SET_BUS_WIDTH 4 bits Fail Status = 0x%x\n", Status));
   1594         goto Exit;
   1595       }
   1596 
   1597       Status = SDHostIo->SetBusWidth (SDHostIo, 4);
   1598       if (EFI_ERROR (Status)) {
   1599         goto Exit;
   1600       }
   1601       CardData->CurrentBusWidth = 4;
   1602 
   1603 
   1604       if ((SDHostIo->HostCapability.HighSpeedSupport == FALSE) ||
   1605           ((CardData->CSDRegister.CCC & BIT10) != BIT10)) {
   1606         //
   1607         // Host must support high speed
   1608         // Card must support Switch function
   1609         //
   1610         goto Exit;
   1611       }
   1612 
   1613       //
   1614       //Mode = 0, group 1, function 1, check operation
   1615       //
   1616       Argument    = 0xFFFF01;
   1617       ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
   1618 
   1619       Status  = SendCommand (
   1620                   CardData,
   1621                   SWITCH_FUNC,
   1622                   Argument,
   1623                   InData,
   1624                   CardData->AlignedBuffer,
   1625                   sizeof (SWITCH_STATUS),
   1626                   ResponseR1,
   1627                   TIMEOUT_COMMAND,
   1628                   (UINT32*)&(CardData->CardStatus)
   1629                   );
   1630       if (EFI_ERROR (Status)) {
   1631         goto Exit;
   1632       }
   1633       CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
   1634 
   1635       if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
   1636           ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
   1637         //
   1638         // 1. SD 1.1 card does not suppport busy bit
   1639         // 2. Ready state
   1640         //
   1641         //
   1642 
   1643         //
   1644         //Mode = 1, group 1, function 1, BIT31 set means set mode
   1645         //
   1646         Argument = 0xFFFF01 | BIT31;
   1647         ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
   1648 
   1649         Status  = SendCommand (
   1650                     CardData,
   1651                     SWITCH_FUNC,
   1652                     Argument,
   1653                     InData,
   1654                     CardData->AlignedBuffer,
   1655                     sizeof (SWITCH_STATUS),
   1656                     ResponseR1,
   1657                     TIMEOUT_COMMAND,
   1658                    (UINT32*)&(CardData->CardStatus)
   1659                    );
   1660          if (EFI_ERROR (Status)) {
   1661             goto Exit;
   1662          }
   1663          CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
   1664 
   1665          if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
   1666             ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
   1667           //
   1668           // 1. SD 1.1 card does not suppport busy bit
   1669           // 2. Ready state
   1670           //
   1671 
   1672           //
   1673           // 8 clocks, (1/ 25M) * 8 ==> 320 us, so 1ms > 0.32 ms
   1674           //
   1675           gBS->Stall (1000);
   1676 
   1677           //
   1678           //Change host clock
   1679           //
   1680           Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_SD_PP_HIGH);
   1681           if (EFI_ERROR (Status)) {
   1682             goto Exit;
   1683           }
   1684 
   1685          }
   1686       }
   1687   }
   1688   if (!((CardData->ExtCSDRegister.CARD_TYPE & BIT2) ||
   1689       (CardData->ExtCSDRegister.CARD_TYPE & BIT3))) {
   1690 
   1691   //
   1692   // Set Block Length, to improve compatibility in case of some cards
   1693   //
   1694   Status  = SendCommand (
   1695                 CardData,
   1696               SET_BLOCKLEN,
   1697               512,
   1698               NoData,
   1699               NULL,
   1700               0,
   1701               ResponseR1,
   1702               TIMEOUT_COMMAND,
   1703               (UINT32*)&(CardData->CardStatus)
   1704               );
   1705   if (EFI_ERROR (Status)) {
   1706     DEBUG((EFI_D_ERROR, "SET_BLOCKLEN Fail Status = 0x%x\n", Status));
   1707     goto Exit;
   1708   }
   1709   }
   1710   SDHostIo->SetBlockLength (SDHostIo, 512);
   1711 
   1712 
   1713 Exit:
   1714   return Status;
   1715 }
   1716 
   1717