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