1/** @file
2
3MMC/SD transfer specific functions
4
5Copyright (c) 2013-2015 Intel Corporation.
6
7This program and the accompanying materials
8are licensed and made available under the terms and conditions of the BSD License
9which accompanies this distribution.  The full text of the license may be found at
10http://opensource.org/licenses/bsd-license.php
11
12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13WITHOUT 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**/
28EFI_STATUS
29CheckCardStatus (
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**/
138EFI_STATUS
139SendCommand (
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**/
201EFI_STATUS
202SendAppCommand (
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**/
292EFI_STATUS
293FastIO (
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
340Exit:
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**/
353EFI_STATUS
354PutCardInactive (
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**/
387EFI_STATUS
388CaculateCardParameter (
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
530Exit:
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**/
545EFI_STATUS
546MMCCardBusWidthTest (
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
635Exit:
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**/
652EFI_STATUS
653GetCardType (
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
831Exit:
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**/
846EFI_STATUS
847MMCCardVoltageSelection (
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
950Exit:
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**/
966EFI_STATUS
967MMCCardSetBusWidth (
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
1064Exit:
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**/
1078EFI_STATUS
1079MMCSDCardInit (
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
1713Exit:
1714  return Status;
1715}
1716
1717