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