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