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   UINT8                      Retry;
    853   UINT32                     TimeOut;
    854 
    855   Status   = EFI_SUCCESS;
    856   //
    857   //First try the high voltage, then if supported choose the low voltage
    858   //
    859 
    860     for (Retry = 0; Retry < 3; Retry++) {
    861       //
    862       // To bring back the normal MMC card to work
    863       // after sending the SD command. Otherwise some
    864       // card could not work
    865 
    866       Status  = SendCommand (
    867                 CardData,
    868                   GO_IDLE_STATE,
    869                   0,
    870                   NoData,
    871                   NULL,
    872                   0,
    873                   ResponseNo,
    874                   TIMEOUT_COMMAND,
    875                   NULL
    876                   );
    877       if (EFI_ERROR (Status)) {
    878         DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
    879         continue;
    880       }
    881       //
    882       //CE-ATA device needs long delay
    883       //
    884       gBS->Stall ((Retry + 1) * 50 * 1000);
    885 
    886       //
    887       //Get OCR register to check voltage support, first time the OCR is 0
    888       //
    889       Status  = SendCommand (
    890                 CardData,
    891                   SEND_OP_COND,
    892                   0,
    893                   NoData,
    894                   NULL,
    895                   0,
    896                   ResponseR3,
    897                   TIMEOUT_COMMAND,
    898                   (UINT32*)&(CardData->OCRRegister)
    899                   );
    900       if (!EFI_ERROR (Status)) {
    901         break;
    902       }
    903     }
    904 
    905     if (Retry == 3) {
    906       DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
    907       Status = EFI_DEVICE_ERROR;
    908       goto Exit;
    909     }
    910 
    911     //
    912     //TimeOut Value, 5000 * 100 * 1000 = 5 s
    913     //
    914     TimeOut = 5000;
    915 
    916     do {
    917       Status  = SendCommand (
    918                 CardData,
    919                   SEND_OP_COND,
    920                   0x40300000,
    921                   NoData,
    922                   NULL,
    923                   0,
    924                   ResponseR3,
    925                   TIMEOUT_COMMAND,
    926                   (UINT32*)&(CardData->OCRRegister)
    927                   );
    928       if (EFI_ERROR (Status)) {
    929         DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
    930         goto Exit;
    931       }
    932 
    933       gBS->Stall (1 * 1000);
    934       TimeOut--;
    935       if (TimeOut == 0) {
    936         Status = EFI_TIMEOUT;
    937       DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
    938         goto Exit;
    939       }
    940     } while (CardData->OCRRegister.Busy != 1);
    941 
    942   if (CardData->OCRRegister.AccessMode == 2) // eMMC Card uses Sector Addressing - High Capacity
    943     {
    944     DEBUG((EFI_D_INFO, "eMMC Card is High Capacity\n"));
    945     CardData->CardType = MMCCardHighCap;
    946   }
    947 
    948 Exit:
    949   return Status;
    950 
    951 }
    952 
    953 /**
    954   This function set the bus and device width for MMC card
    955 
    956   @param  CardData               Pointer to CARD_DATA.
    957   @param  Width                  1, 4, 8 bits.
    958 
    959   @retval EFI_SUCCESS
    960   @retval EFI_UNSUPPORTED
    961   @retval EFI_INVALID_PARAMETER
    962 
    963 **/
    964 EFI_STATUS
    965 MMCCardSetBusWidth (
    966   IN  CARD_DATA              *CardData,
    967   IN  UINT8                  BusWidth,
    968   IN  BOOLEAN                EnableDDRMode
    969   )
    970 {
    971   EFI_STATUS                 Status;
    972   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
    973   SWITCH_ARGUMENT            SwitchArgument;
    974   UINT8                      Value;
    975 
    976   SDHostIo = CardData->SDHostIo;
    977   Value = 0;
    978   switch (BusWidth) {
    979     case 8:
    980       if (EnableDDRMode)
    981         Value = 6;
    982       else
    983       Value = 2;
    984       break;
    985 
    986     case 4:
    987       if (EnableDDRMode)
    988         Value = 5;
    989       else
    990       Value = 1;
    991       break;
    992 
    993     case 1:
    994       if (EnableDDRMode)    // Bus width 1 is not supported in ddr mode
    995         return EFI_UNSUPPORTED;
    996       Value = 0;
    997       break;
    998 
    999     default:
   1000      ASSERT(0);
   1001   }
   1002 
   1003 
   1004   ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1005   SwitchArgument.CmdSet = 0;
   1006   SwitchArgument.Value  = Value;
   1007   SwitchArgument.Index  = (UINT32)((UINTN)
   1008   (&(CardData->ExtCSDRegister.BUS_WIDTH)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1009   SwitchArgument.Access = WriteByte_Mode;
   1010   Status  = SendCommand (
   1011               CardData,
   1012               SWITCH,
   1013               *(UINT32*)&SwitchArgument,
   1014               NoData,
   1015               NULL,
   1016               0,
   1017               ResponseR1b,
   1018               TIMEOUT_COMMAND,
   1019               (UINT32*)&(CardData->CardStatus)
   1020               );
   1021   if (!EFI_ERROR (Status)) {
   1022      Status  = SendCommand (
   1023                  CardData,
   1024                  SEND_STATUS,
   1025                  (CardData->Address << 16),
   1026                  NoData,
   1027                  NULL,
   1028                  0,
   1029                  ResponseR1,
   1030                  TIMEOUT_COMMAND,
   1031                  (UINT32*)&(CardData->CardStatus)
   1032                  );
   1033     if (EFI_ERROR (Status)) {
   1034       DEBUG((EFI_D_ERROR, "SWITCH %d bits Fail\n", BusWidth));
   1035       goto Exit;
   1036     } else {
   1037       DEBUG((EFI_D_ERROR, "MMCCardSetBusWidth:SWITCH Card Status:0x%x\n", *(UINT32*)&(CardData->CardStatus)));
   1038       Status = SDHostIo->SetBusWidth (SDHostIo, BusWidth);
   1039       if (EFI_ERROR (Status)) {
   1040          DEBUG((EFI_D_ERROR, "SWITCH set %d bits Fail\n", BusWidth));
   1041          goto Exit;
   1042       }
   1043       gBS->Stall (5 * 1000);
   1044     }
   1045   }
   1046 
   1047   if (!EnableDDRMode) {     // CMD19 and CMD14 are illegal commands in ddr mode
   1048   //if (EFI_ERROR (Status)) {
   1049   //  DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest: Fail to enable high speed mode\n"));
   1050   //  goto Exit;
   1051   //}
   1052 
   1053   Status = MMCCardBusWidthTest (CardData, BusWidth);
   1054   if (EFI_ERROR (Status)) {
   1055     DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest %d bit Fail\n", BusWidth));
   1056     goto Exit;
   1057     }
   1058   }
   1059 
   1060   CardData->CurrentBusWidth = BusWidth;
   1061 
   1062 Exit:
   1063   return Status;
   1064 }
   1065 
   1066 
   1067 /**
   1068   MMC/SD card init function
   1069 
   1070   @param  CardData             Pointer to CARD_DATA.
   1071 
   1072   @return EFI_SUCCESS
   1073   @return others
   1074 
   1075 **/
   1076 EFI_STATUS
   1077 MMCSDCardInit (
   1078   IN  CARD_DATA              *CardData
   1079   )
   1080 {
   1081   EFI_STATUS                 Status;
   1082   EFI_SD_HOST_IO_PROTOCOL    *SDHostIo;
   1083   SWITCH_ARGUMENT            SwitchArgument;
   1084   UINT32                     Data;
   1085   UINT32                     Argument;
   1086   UINT32                     nIndex;
   1087   UINT8                      PowerValue;
   1088   BOOLEAN                    EnableDDRMode;
   1089 
   1090   ASSERT(CardData != NULL);
   1091   SDHostIo                  = CardData->SDHostIo;
   1092   EnableDDRMode             = FALSE;
   1093 
   1094   CardData->CardType = UnknownCard;
   1095   Status = GetCardType (CardData);
   1096   if (EFI_ERROR (Status)) {
   1097     goto Exit;
   1098   }
   1099   DEBUG((DEBUG_INFO, "CardData->CardType  0x%x\n", CardData->CardType));
   1100 
   1101   ASSERT (CardData->CardType != UnknownCard);
   1102   //
   1103   //MMC, SD card need host auto stop command support
   1104   //
   1105   SDHostIo->EnableAutoStopCmd (SDHostIo, TRUE);
   1106 
   1107   if (CardData->CardType == MMCCard) {
   1108     Status = MMCCardVoltageSelection (CardData);
   1109     if (EFI_ERROR(Status)) {
   1110       goto Exit;
   1111     }
   1112   }
   1113 
   1114   //
   1115   // Get CID Register
   1116   //
   1117   Status  = SendCommand (
   1118               CardData,
   1119               ALL_SEND_CID,
   1120               0,
   1121               NoData,
   1122               NULL,
   1123               0,
   1124               ResponseR2,
   1125               TIMEOUT_COMMAND,
   1126               (UINT32*)&(CardData->CIDRegister)
   1127               );
   1128   if (EFI_ERROR (Status)) {
   1129     DEBUG((EFI_D_ERROR, "ALL_SEND_CID Fail Status = 0x%x\n", Status));
   1130     goto Exit;
   1131   } else {
   1132     // Dump out the Card ID data
   1133     DEBUG((EFI_D_INFO, "Product Name: "));
   1134     for ( nIndex=0; nIndex<6; nIndex++ ) {
   1135       DEBUG((EFI_D_INFO, "%c", CardData->CIDRegister.PNM[nIndex]));
   1136     }
   1137     DEBUG((EFI_D_INFO, "\nApplication ID : %d\n", CardData->CIDRegister.OID));
   1138     DEBUG((EFI_D_INFO, "Manufacturer ID: %d\n", CardData->CIDRegister.MID));
   1139     DEBUG((EFI_D_INFO, "Revision ID    : %d\n", CardData->CIDRegister.PRV));
   1140     DEBUG((EFI_D_INFO, "Serial Number  : %d\n", CardData->CIDRegister.PSN));
   1141   }
   1142 
   1143   //
   1144   //SET_RELATIVE_ADDR
   1145   //
   1146   if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
   1147     //
   1148     //Hard code the RCA address
   1149     //
   1150     CardData->Address = 1;
   1151 
   1152     //
   1153     // Set RCA Register
   1154     //
   1155     Status  = SendCommand (
   1156                 CardData,
   1157                 SET_RELATIVE_ADDR,
   1158                 (CardData->Address << 16),
   1159                 NoData,
   1160                 NULL,
   1161                 0,
   1162                 ResponseR1,
   1163                 TIMEOUT_COMMAND,
   1164                 (UINT32*)&(CardData->CardStatus)
   1165                 );
   1166     if (EFI_ERROR (Status)) {
   1167       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1168       goto Exit;
   1169     }
   1170   } else {
   1171     Data = 0;
   1172     Status  = SendCommand (
   1173                 CardData,
   1174                 SET_RELATIVE_ADDR,
   1175                 0,
   1176                 NoData,
   1177                 NULL,
   1178                 0,
   1179                 ResponseR6,
   1180                 TIMEOUT_COMMAND,
   1181                 &Data
   1182                 );
   1183     if (EFI_ERROR (Status)) {
   1184       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1185       goto Exit;
   1186     }
   1187 
   1188     CardData->Address = (UINT16)(Data >> 16);
   1189     *(UINT32*)&CardData->CardStatus      = Data & 0x1FFF;
   1190     CardData->CardStatus.ERROR           = (Data >> 13) & 0x1;
   1191     CardData->CardStatus.ILLEGAL_COMMAND = (Data >> 14) & 0x1;
   1192     CardData->CardStatus.COM_CRC_ERROR   = (Data >> 15) & 0x1;
   1193     Status = CheckCardStatus (*(UINT32*)&CardData->CardStatus);
   1194     if (EFI_ERROR (Status)) {
   1195       DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
   1196       goto Exit;
   1197     }
   1198   }
   1199 
   1200   //
   1201   // Get CSD Register
   1202   //
   1203   Status  = SendCommand (
   1204               CardData,
   1205               SEND_CSD,
   1206               (CardData->Address << 16),
   1207               NoData,
   1208               NULL,
   1209               0,
   1210               ResponseR2,
   1211               TIMEOUT_COMMAND,
   1212               (UINT32*)&(CardData->CSDRegister)
   1213               );
   1214   if (EFI_ERROR (Status)) {
   1215     DEBUG((EFI_D_ERROR, "SEND_CSD Fail Status = 0x%x\n", Status));
   1216     goto Exit;
   1217   }
   1218 
   1219   DEBUG((EFI_D_INFO, "CardData->CSDRegister.SPEC_VERS = 0x%x\n", CardData->CSDRegister.SPEC_VERS));
   1220   DEBUG((EFI_D_INFO, "CardData->CSDRegister.CSD_STRUCTURE = 0x%x\n", CardData->CSDRegister.CSD_STRUCTURE));
   1221 
   1222   Status = CaculateCardParameter (CardData);
   1223   if (EFI_ERROR (Status)) {
   1224     goto Exit;
   1225   }
   1226 
   1227 
   1228   //
   1229   // It is platform and hardware specific, need hadrware engineer input
   1230   //
   1231   if (CardData->CSDRegister.DSR_IMP == 1) {
   1232     //
   1233     // Default is 0x404
   1234     //
   1235     Status  = SendCommand (
   1236                 CardData,
   1237                 SET_DSR,
   1238                 (DEFAULT_DSR_VALUE << 16),
   1239                 NoData,
   1240                 NULL,
   1241                 0,
   1242                 ResponseNo,
   1243                 TIMEOUT_COMMAND,
   1244                 NULL
   1245                 );
   1246     if (EFI_ERROR (Status)) {
   1247       DEBUG((EFI_D_ERROR, "SET_DSR Fail Status = 0x%x\n", Status));
   1248       //
   1249       // Assume can operate even fail
   1250       //
   1251     }
   1252   }
   1253   //
   1254   //Change clock frequency from 400KHz to max supported when not in high speed mode
   1255   //
   1256   Status = SDHostIo->SetClockFrequency (SDHostIo, CardData->MaxFrequency);
   1257   if (EFI_ERROR (Status)) {
   1258   DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
   1259   goto Exit;
   1260   }
   1261 
   1262   //
   1263   //Put the card into tran state
   1264   //
   1265   Status = SendCommand (
   1266              CardData,
   1267              SELECT_DESELECT_CARD,
   1268              (CardData->Address << 16),
   1269              NoData,
   1270              NULL,
   1271              0,
   1272              ResponseR1,
   1273              TIMEOUT_COMMAND,
   1274              (UINT32*)&(CardData->CardStatus)
   1275              );
   1276   if (EFI_ERROR (Status)) {
   1277     DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD Fail Status = 0x%x\n", Status));
   1278     goto Exit;
   1279   }
   1280 
   1281   //
   1282   // No spec requirment, can be adjusted
   1283   //
   1284   gBS->Stall (5 * 1000);
   1285   //
   1286   // No need to do so
   1287   //
   1288   //
   1289   Status  = SendCommand (
   1290               CardData,
   1291               SEND_STATUS,
   1292               (CardData->Address << 16),
   1293               NoData,
   1294               NULL,
   1295               0,
   1296               ResponseR1,
   1297               TIMEOUT_COMMAND,
   1298               (UINT32*)&(CardData->CardStatus)
   1299               );
   1300   if (EFI_ERROR (Status)) {
   1301      DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD SEND_STATUS Fail Status = 0x%x\n", Status));
   1302      goto Exit;
   1303   }
   1304   //
   1305   //if the SPEC_VERS indicates a version 4.0 or higher
   1306   //The card is a high speed card and support Switch
   1307   //and Send_ext_csd command
   1308   //otherwise it is an old card
   1309   //
   1310 
   1311   if (CardData->CardType == MMCCard  || CardData->CardType == MMCCardHighCap) {
   1312     //
   1313     //Only V4.0 and above supports more than 1 bits and high speed
   1314     //
   1315     if (CardData->CSDRegister.SPEC_VERS >= 4) {
   1316     //
   1317       //Get ExtCSDRegister
   1318       //
   1319       Status  = SendCommand (
   1320                   CardData,
   1321                   SEND_EXT_CSD,
   1322                   0x0,
   1323                   InData,
   1324                   CardData->AlignedBuffer,
   1325                   sizeof (EXT_CSD),
   1326                   ResponseR1,
   1327                   TIMEOUT_DATA,
   1328                   (UINT32*)&(CardData->CardStatus)
   1329                   );
   1330       if (EFI_ERROR (Status)) {
   1331         DEBUG((EFI_D_ERROR, "SEND_EXT_CSD Fail Status = 0x%x\n", Status));
   1332         goto Exit;
   1333       }
   1334 
   1335       CopyMem (&(CardData->ExtCSDRegister), CardData->AlignedBuffer, sizeof (EXT_CSD));
   1336 
   1337       //
   1338       // Recaculate the block number for >2G MMC card
   1339       //
   1340       Data  = (CardData->ExtCSDRegister.SEC_COUNT[0]) |
   1341               (CardData->ExtCSDRegister.SEC_COUNT[1] << 8) |
   1342               (CardData->ExtCSDRegister.SEC_COUNT[2] << 16) |
   1343               (CardData->ExtCSDRegister.SEC_COUNT[3] << 24);
   1344 
   1345       if (Data != 0) {
   1346         CardData->BlockNumber = Data;
   1347       }
   1348       DEBUG((DEBUG_INFO, "CardData->BlockNumber  %d\n", Data));
   1349       DEBUG((EFI_D_ERROR, "CardData->ExtCSDRegister.CARD_TYPE -> %d\n", (UINTN)CardData->ExtCSDRegister.CARD_TYPE));
   1350       if ((CardData->ExtCSDRegister.CARD_TYPE & BIT2)||
   1351           (CardData->ExtCSDRegister.CARD_TYPE & BIT3)) {
   1352           //DEBUG((DEBUG_INFO, "To enable DDR mode\n"));
   1353           //EnableDDRMode = TRUE;
   1354       }
   1355       //
   1356       // Check current chipset capability and the plugged-in card
   1357       // whether supports HighSpeed
   1358       //
   1359       if (SDHostIo->HostCapability.HighSpeedSupport) {
   1360 
   1361         //
   1362         //Change card timing to high speed interface timing
   1363         //
   1364         ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1365         SwitchArgument.CmdSet = 0;
   1366         SwitchArgument.Value  = 1;
   1367         SwitchArgument.Index  = (UINT32)((UINTN)
   1368         (&(CardData->ExtCSDRegister.HS_TIMING)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1369         SwitchArgument.Access = WriteByte_Mode;
   1370         Status  = SendCommand (
   1371                     CardData,
   1372                     SWITCH,
   1373                     *(UINT32*)&SwitchArgument,
   1374                     NoData,
   1375                     NULL,
   1376                     0,
   1377                     ResponseR1b,
   1378                     TIMEOUT_COMMAND,
   1379                     (UINT32*)&(CardData->CardStatus)
   1380                     );
   1381         if (EFI_ERROR (Status)) {
   1382           DEBUG((EFI_D_ERROR, "MMCSDCardInit:SWITCH frequency Fail Status = 0x%x\n", Status));
   1383         }
   1384 
   1385         gBS->Stall (5 * 1000);
   1386 
   1387 
   1388         if (!EFI_ERROR (Status)) {
   1389           Status  = SendCommand (
   1390                       CardData,
   1391                       SEND_STATUS,
   1392                       (CardData->Address << 16),
   1393                       NoData,
   1394                       NULL,
   1395                       0,
   1396                       ResponseR1,
   1397                       TIMEOUT_COMMAND,
   1398                       (UINT32*)&(CardData->CardStatus)
   1399                       );
   1400           if (!EFI_ERROR (Status)) {
   1401             if (EnableDDRMode) {
   1402               DEBUG((EFI_D_ERROR, "Enable ddr mode on host controller\n"));
   1403               SDHostIo->SetDDRMode (SDHostIo, TRUE);
   1404             } else  {
   1405               DEBUG((EFI_D_ERROR, "Enable high speed mode on host controller\n"));
   1406               SDHostIo->SetHighSpeedMode (SDHostIo, TRUE);
   1407             }
   1408           //
   1409           // Change host clock to support high speed and enable chispet to
   1410           // support speed
   1411           //
   1412             if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1413               Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP_HIGH);
   1414             } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1415               Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP);
   1416             } else {
   1417               Status = EFI_UNSUPPORTED;
   1418             }
   1419             if (EFI_ERROR (Status)) {
   1420               DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
   1421               goto Exit;
   1422             }
   1423             //
   1424             // It seems no need to stall after changing bus freqeuncy.
   1425             // It is said that the freqeuncy can be changed at any time. Just appends 8 clocks after command.
   1426             // But SetClock alreay has delay.
   1427             //
   1428           }
   1429         }
   1430 
   1431       }
   1432 
   1433 
   1434 
   1435       //
   1436       // Prefer wide bus width for performance
   1437       //
   1438       //
   1439       // Set to BusWidth bits mode, only version 4.0 or above support more than 1 bits
   1440       //
   1441       if (SDHostIo->HostCapability.BusWidth8 == TRUE) {
   1442          Status = MMCCardSetBusWidth (CardData, 8, EnableDDRMode);
   1443          if (EFI_ERROR (Status)) {
   1444             //
   1445             // CE-ATA may support 8 bits and 4 bits, but has no software method for detection
   1446             //
   1447             Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
   1448             if (EFI_ERROR (Status)) {
   1449               goto Exit;
   1450             }
   1451          }
   1452       } else if (SDHostIo->HostCapability.BusWidth4 == TRUE) {
   1453          Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
   1454          if (EFI_ERROR (Status)) {
   1455            goto Exit;
   1456          }
   1457       }
   1458 
   1459       PowerValue = 0;
   1460 
   1461       if (CardData->CurrentBusWidth == 8) {
   1462         if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1463           PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
   1464           PowerValue = PowerValue >> 4;
   1465         } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1466           PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
   1467           PowerValue = PowerValue >> 4;
   1468         }
   1469       } else if (CardData->CurrentBusWidth == 4) {
   1470          if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
   1471           PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
   1472           PowerValue = PowerValue & 0xF;
   1473          } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
   1474            PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
   1475            PowerValue = PowerValue & 0xF;
   1476          }
   1477       }
   1478 
   1479       if (PowerValue != 0) {
   1480         //
   1481         //Update Power Class
   1482         //
   1483         ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
   1484         SwitchArgument.CmdSet = 0;
   1485         SwitchArgument.Value  = PowerValue;
   1486         SwitchArgument.Index  = (UINT32)((UINTN)
   1487         (&(CardData->ExtCSDRegister.POWER_CLASS)) - (UINTN)(&(CardData->ExtCSDRegister)));
   1488         SwitchArgument.Access = WriteByte_Mode;
   1489         Status  = SendCommand (
   1490                     CardData,
   1491                     SWITCH,
   1492                     *(UINT32*)&SwitchArgument,
   1493                     NoData,
   1494                     NULL,
   1495                     0,
   1496                     ResponseR1b,
   1497                     TIMEOUT_COMMAND,
   1498                     (UINT32*)&(CardData->CardStatus)
   1499                     );
   1500          if (!EFI_ERROR (Status)) {
   1501            Status  = SendCommand (
   1502                        CardData,
   1503                        SEND_STATUS,
   1504                        (CardData->Address << 16),
   1505                        NoData,
   1506                        NULL,
   1507                        0,
   1508                        ResponseR1,
   1509                        TIMEOUT_COMMAND,
   1510                        (UINT32*)&(CardData->CardStatus)
   1511                        );
   1512            if (EFI_ERROR (Status)) {
   1513              DEBUG((EFI_D_ERROR, "SWITCH Power Class Fail Status = 0x%x\n", Status));
   1514            }
   1515            //gBS->Stall (10 * 1000);
   1516          }
   1517       }
   1518 
   1519 
   1520 
   1521     } else {
   1522 
   1523 
   1524       DEBUG((EFI_D_ERROR, "MMC Card version %d only supportes 1 bits at lower transfer speed\n",CardData->CSDRegister.SPEC_VERS));
   1525     }
   1526   } else {
   1527       //
   1528       // Pin 1, at power up this line has a 50KOhm pull up enabled in the card.
   1529       // This pull-up should be disconnected by the user, during regular data transfer,
   1530       // with SET_CLR_CARD_DETECT (ACMD42) command
   1531       //
   1532       Status  = SendAppCommand (
   1533                   CardData,
   1534                   SET_CLR_CARD_DETECT,
   1535                   0,
   1536                   NoData,
   1537                   NULL,
   1538                   0,
   1539                   ResponseR1,
   1540                   TIMEOUT_COMMAND,
   1541                   (UINT32*)&(CardData->CardStatus)
   1542                   );
   1543       if (EFI_ERROR (Status)) {
   1544         DEBUG((EFI_D_ERROR, "SET_CLR_CARD_DETECT Fail Status = 0x%x\n", Status));
   1545         goto Exit;
   1546       }
   1547 
   1548       /*
   1549       //
   1550       // Don't rely on SCR and SD status, some cards have unexpected SCR.
   1551       // It only sets private section, the other bits are 0
   1552       // such as Sandisk Ultra II 4.0G, KinSton mini SD 128M, Toshiba 2.0GB
   1553       // Some card even fail this command, KinSton SD 4GB
   1554       //
   1555       Status  = SendAppCommand (
   1556                   CardData,
   1557                   SEND_SCR,
   1558                   0,
   1559                   InData,
   1560                   (UINT8*)&(CardData->SCRRegister),
   1561                   sizeof(SCR),
   1562                   ResponseR1,
   1563                   TIMEOUT_COMMAND,
   1564                   (UINT32*)&(CardData->CardStatus)
   1565                   );
   1566       if (EFI_ERROR (Status)) {
   1567         goto Exit;
   1568       }
   1569 
   1570       //
   1571       // SD memory card at least supports 1 and 4 bits.
   1572       //
   1573       // ASSERT ((CardData->SCRRegister.SD_BUS_WIDTH & (BIT0 | BIT2)) == (BIT0 | BIT2));
   1574       */
   1575 
   1576       //
   1577       // Set Bus Width to 4
   1578       //
   1579       Status  = SendAppCommand (
   1580                   CardData,
   1581                   SET_BUS_WIDTH,
   1582                   SD_BUS_WIDTH_4,
   1583                   NoData,
   1584                   NULL,
   1585                   0,
   1586                   ResponseR1,
   1587                   TIMEOUT_COMMAND,
   1588                   (UINT32*)&(CardData->CardStatus)
   1589                   );
   1590       if (EFI_ERROR (Status)) {
   1591         DEBUG((EFI_D_ERROR, "SET_BUS_WIDTH 4 bits Fail Status = 0x%x\n", Status));
   1592         goto Exit;
   1593       }
   1594 
   1595       Status = SDHostIo->SetBusWidth (SDHostIo, 4);
   1596       if (EFI_ERROR (Status)) {
   1597         goto Exit;
   1598       }
   1599       CardData->CurrentBusWidth = 4;
   1600 
   1601 
   1602       if ((SDHostIo->HostCapability.HighSpeedSupport == FALSE) ||
   1603           ((CardData->CSDRegister.CCC & BIT10) != BIT10)) {
   1604         //
   1605         // Host must support high speed
   1606         // Card must support Switch function
   1607         //
   1608         goto Exit;
   1609       }
   1610 
   1611       //
   1612       //Mode = 0, group 1, function 1, check operation
   1613       //
   1614       Argument    = 0xFFFF01;
   1615       ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
   1616 
   1617       Status  = SendCommand (
   1618                   CardData,
   1619                   SWITCH_FUNC,
   1620                   Argument,
   1621                   InData,
   1622                   CardData->AlignedBuffer,
   1623                   sizeof (SWITCH_STATUS),
   1624                   ResponseR1,
   1625                   TIMEOUT_COMMAND,
   1626                   (UINT32*)&(CardData->CardStatus)
   1627                   );
   1628       if (EFI_ERROR (Status)) {
   1629         goto Exit;
   1630       }
   1631       CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
   1632 
   1633       if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
   1634           ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
   1635         //
   1636         // 1. SD 1.1 card does not suppport busy bit
   1637         // 2. Ready state
   1638         //
   1639         //
   1640 
   1641         //
   1642         //Mode = 1, group 1, function 1, BIT31 set means set mode
   1643         //
   1644         Argument = 0xFFFF01 | BIT31;
   1645         ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
   1646 
   1647         Status  = SendCommand (
   1648                     CardData,
   1649                     SWITCH_FUNC,
   1650                     Argument,
   1651                     InData,
   1652                     CardData->AlignedBuffer,
   1653                     sizeof (SWITCH_STATUS),
   1654                     ResponseR1,
   1655                     TIMEOUT_COMMAND,
   1656                    (UINT32*)&(CardData->CardStatus)
   1657                    );
   1658          if (EFI_ERROR (Status)) {
   1659             goto Exit;
   1660          }
   1661          CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
   1662 
   1663          if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
   1664             ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
   1665           //
   1666           // 1. SD 1.1 card does not suppport busy bit
   1667           // 2. Ready state
   1668           //
   1669 
   1670           //
   1671           // 8 clocks, (1/ 25M) * 8 ==> 320 us, so 1ms > 0.32 ms
   1672           //
   1673           gBS->Stall (1000);
   1674 
   1675           //
   1676           //Change host clock
   1677           //
   1678           Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_SD_PP_HIGH);
   1679           if (EFI_ERROR (Status)) {
   1680             goto Exit;
   1681           }
   1682 
   1683          }
   1684       }
   1685   }
   1686   if (!((CardData->ExtCSDRegister.CARD_TYPE & BIT2) ||
   1687       (CardData->ExtCSDRegister.CARD_TYPE & BIT3))) {
   1688 
   1689   //
   1690   // Set Block Length, to improve compatibility in case of some cards
   1691   //
   1692   Status  = SendCommand (
   1693                 CardData,
   1694               SET_BLOCKLEN,
   1695               512,
   1696               NoData,
   1697               NULL,
   1698               0,
   1699               ResponseR1,
   1700               TIMEOUT_COMMAND,
   1701               (UINT32*)&(CardData->CardStatus)
   1702               );
   1703   if (EFI_ERROR (Status)) {
   1704     DEBUG((EFI_D_ERROR, "SET_BLOCKLEN Fail Status = 0x%x\n", Status));
   1705     goto Exit;
   1706   }
   1707   }
   1708   SDHostIo->SetBlockLength (SDHostIo, 512);
   1709 
   1710 
   1711 Exit:
   1712   return Status;
   1713 }
   1714 
   1715