]> git.proxmox.com Git - mirror_edk2.git/blob - QuarkSocPkg/QuarkSouthCluster/Sdio/Dxe/SDMediaDeviceDxe/MMCSDTransfer.c
QuarkSocPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / QuarkSocPkg / QuarkSouthCluster / Sdio / Dxe / SDMediaDeviceDxe / MMCSDTransfer.c
1 /** @file
2
3 MMC/SD transfer specific functions
4
5 Copyright (c) 2013-2015 Intel Corporation.
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9 **/
10
11 #include "SDMediaDevice.h"
12
13 /**
14 Check card status, print the debug info and check the error
15
16 @param Status Status got from card status register.
17
18 @retval EFI_SUCCESS
19 @retval EFI_DEVICE_ERROR
20
21 **/
22 EFI_STATUS
23 CheckCardStatus (
24 IN UINT32 Status
25 )
26 {
27 CARD_STATUS *CardStatus;
28 CardStatus = (CARD_STATUS*)(&Status);
29
30 if (CardStatus->ADDRESS_OUT_OF_RANGE) {
31 DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_OUT_OF_RANGE\n"));
32 }
33
34 if (CardStatus->ADDRESS_MISALIGN) {
35 DEBUG ((EFI_D_ERROR, "CardStatus: ADDRESS_MISALIGN\n"));
36 }
37
38 if (CardStatus->BLOCK_LEN_ERROR) {
39 DEBUG ((EFI_D_ERROR, "CardStatus: BLOCK_LEN_ERROR\n"));
40 }
41
42 if (CardStatus->ERASE_SEQ_ERROR) {
43 DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_SEQ_ERROR\n"));
44 }
45
46 if (CardStatus->ERASE_PARAM) {
47 DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_PARAM\n"));
48 }
49
50 if (CardStatus->WP_VIOLATION) {
51 DEBUG ((EFI_D_ERROR, "CardStatus: WP_VIOLATION\n"));
52 }
53
54 if (CardStatus->CARD_IS_LOCKED) {
55 DEBUG ((EFI_D_ERROR, "CardStatus: CARD_IS_LOCKED\n"));
56 }
57
58 if (CardStatus->LOCK_UNLOCK_FAILED) {
59 DEBUG ((EFI_D_ERROR, "CardStatus: LOCK_UNLOCK_FAILED\n"));
60 }
61
62 if (CardStatus->COM_CRC_ERROR) {
63 DEBUG ((EFI_D_ERROR, "CardStatus: COM_CRC_ERROR\n"));
64 }
65
66 if (CardStatus->ILLEGAL_COMMAND) {
67 DEBUG ((EFI_D_ERROR, "CardStatus: ILLEGAL_COMMAND\n"));
68 }
69
70 if (CardStatus->CARD_ECC_FAILED) {
71 DEBUG ((EFI_D_ERROR, "CardStatus: CARD_ECC_FAILED\n"));
72 }
73
74 if (CardStatus->CC_ERROR) {
75 DEBUG ((EFI_D_ERROR, "CardStatus: CC_ERROR\n"));
76 }
77
78 if (CardStatus->ERROR) {
79 DEBUG ((EFI_D_ERROR, "CardStatus: ERROR\n"));
80 }
81
82 if (CardStatus->UNDERRUN) {
83 DEBUG ((EFI_D_ERROR, "CardStatus: UNDERRUN\n"));
84 }
85
86 if (CardStatus->OVERRUN) {
87 DEBUG ((EFI_D_ERROR, "CardStatus: OVERRUN\n"));
88 }
89
90 if (CardStatus->CID_CSD_OVERWRITE) {
91 DEBUG ((EFI_D_ERROR, "CardStatus: CID_CSD_OVERWRITE\n"));
92 }
93
94 if (CardStatus->WP_ERASE_SKIP) {
95 DEBUG ((EFI_D_ERROR, "CardStatus: WP_ERASE_SKIP\n"));
96 }
97
98 if (CardStatus->ERASE_RESET) {
99 DEBUG ((EFI_D_ERROR, "CardStatus: ERASE_RESET\n"));
100 }
101
102 if (CardStatus->SWITCH_ERROR) {
103 DEBUG ((EFI_D_ERROR, "CardStatus: SWITCH_ERROR\n"));
104 }
105
106 if ((Status & 0xFCFFA080) != 0) {
107 return EFI_DEVICE_ERROR;
108 }
109
110 return EFI_SUCCESS;
111 }
112
113 /**
114 Send command by using Host IO protocol
115
116 @param This A pointer to the EFI_SD_HOST_IO_PROTOCOL instance.
117 @param CommandIndex The command index to set the command index field of command register.
118 @param Argument Command argument to set the argument field of command register.
119 @param DataType TRANSFER_TYPE, indicates no data, data in or data out.
120 @param Buffer Contains the data read from / write to the device.
121 @param BufferSize The size of the buffer.
122 @param ResponseType RESPONSE_TYPE.
123 @param TimeOut Time out value in 1 ms unit.
124 @param ResponseData Depending on the ResponseType, such as CSD or card status.
125
126 @retval EFI_SUCCESS
127 @retval EFI_INVALID_PARAMETER
128 @retval EFI_UNSUPPORTED
129 @retval EFI_DEVICE_ERROR
130
131 **/
132 EFI_STATUS
133 SendCommand (
134 IN CARD_DATA *CardData,
135 IN UINT16 CommandIndex,
136 IN UINT32 Argument,
137 IN TRANSFER_TYPE DataType,
138 IN UINT8 *Buffer, OPTIONAL
139 IN UINT32 BufferSize,
140 IN RESPONSE_TYPE ResponseType,
141 IN UINT32 TimeOut,
142 OUT UINT32 *ResponseData
143 )
144 {
145
146 EFI_STATUS Status;
147 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
148 SDHostIo = CardData->SDHostIo;
149 if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
150 CommandIndex |= AUTO_CMD12_ENABLE;
151 }
152
153 Status = SDHostIo->SendCommand (
154 SDHostIo,
155 CommandIndex,
156 Argument,
157 DataType,
158 Buffer,
159 BufferSize,
160 ResponseType,
161 TimeOut,
162 ResponseData
163 );
164 if (!EFI_ERROR (Status)) {
165 if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
166 ASSERT(ResponseData != NULL);
167 Status = CheckCardStatus (*ResponseData);
168 }
169 } else {
170 SDHostIo->ResetSDHost (SDHostIo, Reset_DAT_CMD);
171 }
172
173 return Status;
174 }
175
176 /**
177 Send the card APP_CMD command with the following command indicated by CommandIndex
178
179 @param CardData Pointer to CARD_DATA.
180 @param CommandIndex The command index to set the command index field of command register.
181 @param Argument Command argument to set the argument field of command register.
182 @param DataType TRANSFER_TYPE, indicates no data, data in or data out.
183 @param Buffer Contains the data read from / write to the device.
184 @param BufferSize The size of the buffer.
185 @param ResponseType RESPONSE_TYPE.
186 @param TimeOut Time out value in 1 ms unit.
187 @param ResponseData Depending on the ResponseType, such as CSD or card status.
188
189 @retval EFI_SUCCESS
190 @retval EFI_INVALID_PARAMETER
191 @retval EFI_UNSUPPORTED
192 @retval EFI_DEVICE_ERROR
193
194 **/
195 EFI_STATUS
196 SendAppCommand (
197 IN CARD_DATA *CardData,
198 IN UINT16 CommandIndex,
199 IN UINT32 Argument,
200 IN TRANSFER_TYPE DataType,
201 IN UINT8 *Buffer, OPTIONAL
202 IN UINT32 BufferSize,
203 IN RESPONSE_TYPE ResponseType,
204 IN UINT32 TimeOut,
205 OUT UINT32 *ResponseData
206 )
207 {
208
209 EFI_STATUS Status;
210 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
211 UINT8 Index;
212
213 SDHostIo = CardData->SDHostIo;
214 Status = EFI_SUCCESS;
215
216 for (Index = 0; Index < 2; Index++) {
217 Status = SDHostIo->SendCommand (
218 SDHostIo,
219 APP_CMD,
220 (CardData->Address << 16),
221 NoData,
222 NULL,
223 0,
224 ResponseR1,
225 TIMEOUT_COMMAND,
226 (UINT32*)&(CardData->CardStatus)
227 );
228 if (!EFI_ERROR (Status)) {
229 Status = CheckCardStatus (*(UINT32*)&(CardData->CardStatus));
230 if (CardData->CardStatus.SAPP_CMD != 1) {
231 Status = EFI_DEVICE_ERROR;
232 }
233 if (!EFI_ERROR (Status)) {
234 break;
235 }
236 } else {
237 SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
238 }
239 }
240
241 if (EFI_ERROR (Status)) {
242 return Status;
243 }
244 if (CardData->CardType != MMCCard && CardData->CardType != MMCCardHighCap) {
245 CommandIndex |= AUTO_CMD12_ENABLE;
246 }
247
248 Status = SDHostIo->SendCommand (
249 SDHostIo,
250 CommandIndex,
251 Argument,
252 DataType,
253 Buffer,
254 BufferSize,
255 ResponseType,
256 TimeOut,
257 ResponseData
258 );
259 if (!EFI_ERROR (Status)) {
260 if (ResponseType == ResponseR1 || ResponseType == ResponseR1b) {
261 ASSERT(ResponseData != NULL);
262 Status = CheckCardStatus (*ResponseData);
263 }
264 } else {
265 SDHostIo->ResetSDHost (SDHostIo, Reset_Auto);
266 }
267
268 return Status;
269 }
270
271
272 /**
273 Send the card FAST_IO command
274
275 @param CardData Pointer to CARD_DATA.
276 @param RegisterAddress Register Address.
277 @param RegisterData Pointer to register Data.
278 @param Write TRUE for write, FALSE for read.
279
280 @retval EFI_SUCCESS
281 @retval EFI_UNSUPPORTED
282 @retval EFI_INVALID_PARAMETER
283 @retval EFI_DEVICE_ERROR
284
285 **/
286 EFI_STATUS
287 FastIO (
288 IN CARD_DATA *CardData,
289 IN UINT8 RegisterAddress,
290 IN OUT UINT8 *RegisterData,
291 IN BOOLEAN Write
292 )
293 {
294 EFI_STATUS Status;
295 UINT32 Argument;
296 UINT32 Data;
297
298 Status = EFI_SUCCESS;
299
300 if (RegisterData == NULL) {
301 Status = EFI_INVALID_PARAMETER;
302 goto Exit;
303 }
304
305 Argument = (CardData->Address << 16) | (RegisterAddress << 8);
306 if (Write) {
307 Argument |= BIT15 | (*RegisterData);
308 }
309
310 Status = SendCommand (
311 CardData,
312 FAST_IO,
313 Argument,
314 NoData,
315 NULL,
316 0,
317 ResponseR4,
318 TIMEOUT_COMMAND,
319 &Data
320 );
321 if (EFI_ERROR (Status)) {
322 goto Exit;
323 }
324
325 if ((Data & BIT15) == 0) {
326 Status = EFI_DEVICE_ERROR;
327 goto Exit;
328 }
329
330 if (!Write) {
331 *RegisterData = (UINT8)Data;
332 }
333
334 Exit:
335 return Status;
336 }
337
338 /**
339 Send the card GO_INACTIVE_STATE command.
340
341 @param CardData Pointer to CARD_DATA.
342
343 @return EFI_SUCCESS
344 @return others
345
346 **/
347 EFI_STATUS
348 PutCardInactive (
349 IN CARD_DATA *CardData
350 )
351 {
352 EFI_STATUS Status;
353
354
355 Status = SendCommand (
356 CardData,
357 GO_INACTIVE_STATE,
358 (CardData->Address << 16),
359 NoData,
360 NULL,
361 0,
362 ResponseNo,
363 TIMEOUT_COMMAND,
364 NULL
365 );
366
367 return Status;
368
369 }
370
371 /**
372 Get card interested information for CSD rergister
373
374 @param CardData Pointer to CARD_DATA.
375
376 @retval EFI_SUCCESS
377 @retval EFI_UNSUPPORTED
378 @retval EFI_INVALID_PARAMETER
379
380 **/
381 EFI_STATUS
382 CaculateCardParameter (
383 IN CARD_DATA *CardData
384 )
385 {
386 EFI_STATUS Status;
387 UINT32 Frequency;
388 UINT32 Multiple;
389 UINT32 CSize;
390 CSD_SDV2 *CsdSDV2;
391
392 Status = EFI_SUCCESS;
393
394 switch (CardData->CSDRegister.TRAN_SPEED & 0x7) {
395 case 0:
396 Frequency = 100 * 1000;
397 break;
398
399 case 1:
400 Frequency = 1 * 1000 * 1000;
401 break;
402
403 case 2:
404 Frequency = 10 * 1000 * 1000;
405 break;
406
407 case 3:
408 Frequency = 100 * 1000 * 1000;
409 break;
410
411 default:
412 Status = EFI_INVALID_PARAMETER;
413 goto Exit;
414 }
415
416 switch ((CardData->CSDRegister.TRAN_SPEED >> 3) & 0xF) {
417 case 1:
418 Multiple = 10;
419 break;
420
421 case 2:
422 Multiple = 12;
423 break;
424
425 case 3:
426 Multiple = 13;
427 break;
428
429 case 4:
430 Multiple = 15;
431 break;
432
433 case 5:
434 Multiple = 20;
435 break;
436
437 case 6:
438 if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
439 Multiple = 26;
440 } else {
441 Multiple = 25;
442 }
443 break;
444
445 case 7:
446 Multiple = 30;
447 break;
448
449 case 8:
450 Multiple = 35;
451 break;
452
453 case 9:
454 Multiple = 40;
455 break;
456
457 case 10:
458 Multiple = 45;
459 break;
460
461 case 11:
462 if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
463 Multiple = 52;
464 } else {
465 Multiple = 50;
466 }
467 break;
468
469 case 12:
470 Multiple = 55;
471 break;
472
473 case 13:
474 Multiple = 60;
475 break;
476
477 case 14:
478 Multiple = 70;
479 break;
480
481 case 15:
482 Multiple = 80;
483 break;
484
485 default:
486 Status = EFI_INVALID_PARAMETER;
487 goto Exit;
488 }
489
490 Frequency = Frequency * Multiple / 10;
491 CardData->MaxFrequency = Frequency;
492
493 CardData->BlockLen = 1 << CardData->CSDRegister.READ_BL_LEN;
494
495 if (CardData->CardType == SDMemoryCard2High) {
496 ASSERT(CardData->CSDRegister.CSD_STRUCTURE == 1);
497 CsdSDV2 = (CSD_SDV2*)&CardData->CSDRegister;
498 //
499 // The SD Spec 2.0 says (CSize + 1) * 512K is the total size, so block numbber is (CSize + 1) * 1K
500 // the K here means 1024 not 1000
501 //
502 CardData->BlockNumber = DivU64x32 (MultU64x32 (CsdSDV2->C_SIZE + 1, 512 * 1024) , CardData->BlockLen);
503 } else {
504 //
505 // For MMC card > 2G, the block number will be recaculate later
506 //
507 CSize = CardData->CSDRegister.C_SIZELow2 | (CardData->CSDRegister.C_SIZEHigh10 << 2);
508 CardData->BlockNumber = MultU64x32 (LShiftU64 (1, CardData->CSDRegister.C_SIZE_MULT + 2), CSize + 1);
509 }
510
511 //
512 //For >= 2G card, BlockLen may be 1024, but the transfer size is still 512 bytes
513 //
514 if (CardData->BlockLen > 512) {
515 CardData->BlockNumber = DivU64x32 (MultU64x32 (CardData->BlockNumber, CardData->BlockLen), 512);
516 CardData->BlockLen = 512;
517 }
518
519 DEBUG((
520 EFI_D_INFO,
521 "CalculateCardParameter: Card Size: 0x%lx\n", MultU64x32 (CardData->BlockNumber, CardData->BlockLen)
522 ));
523
524 Exit:
525 return Status;
526 }
527
528 /**
529 Test the bus width setting for MMC card.It is used only for verification purpose.
530
531 @param CardData Pointer to CARD_DATA.
532 @param Width 1, 4, 8 bits.
533
534 @retval EFI_SUCCESS
535 @retval EFI_UNSUPPORTED
536 @retval EFI_INVALID_PARAMETER
537
538 **/
539 EFI_STATUS
540 MMCCardBusWidthTest (
541 IN CARD_DATA *CardData,
542 IN UINT32 Width
543 )
544 {
545 EFI_STATUS Status;
546 UINT64 Data;
547 UINT64 Value;
548
549 ASSERT(CardData != NULL);
550
551
552 Value = 0;
553
554 switch (Width) {
555 case 1:
556 Data = 0x80;
557 break;
558
559 case 4:
560 Data = 0x5A;
561 break;
562
563 case 8:
564 Data = 0xAA55;
565 break;
566
567 default:
568 Status = EFI_INVALID_PARAMETER;
569 goto Exit;
570 }
571
572 CopyMem (CardData->AlignedBuffer, &Data, Width);
573 Status = SendCommand (
574 CardData,
575 BUSTEST_W,
576 0,
577 OutData,
578 CardData->AlignedBuffer,
579 Width,
580 ResponseR1,
581 TIMEOUT_COMMAND,
582 (UINT32*)&(CardData->CardStatus)
583 );
584 if (EFI_ERROR (Status)) {
585 DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_W 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
586 goto Exit;
587 }
588
589 gBS->Stall (10 * 1000);
590
591 Data = 0;
592
593 Status = SendCommand (
594 CardData,
595 BUSTEST_R,
596 0,
597 InData,
598 CardData->AlignedBuffer,
599 Width,
600 ResponseR1,
601 TIMEOUT_COMMAND,
602 (UINT32*)&(CardData->CardStatus)
603 );
604 if (EFI_ERROR (Status)) {
605 DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest:SendCommand BUSTEST_R 0x%x\n", *(UINT32*)&(CardData->CardStatus)));
606 goto Exit;
607 }
608 CopyMem (&Data, CardData->AlignedBuffer, Width);
609
610 switch (Width) {
611 case 1:
612 Value = (~(Data ^ 0x80)) & 0xC0;
613 break;
614 case 4:
615 Value = (~(Data ^ 0x5A)) & 0xFF;
616 break;
617 case 8:
618 Value = (~(Data ^ 0xAA55)) & 0xFFFF;
619 break;
620 }
621
622 if (Value == 0) {
623 Status = EFI_SUCCESS;
624 } else {
625 Status = EFI_UNSUPPORTED;
626 }
627
628
629 Exit:
630 return Status;
631 }
632
633 /**
634 This function can detect these card types:
635 1. MMC card
636 2. SD 1.1 card
637 3. SD 2.0 standard card
638 3. SD 2.0 high capacity card
639
640 @param CardData Pointer to CARD_DATA.
641
642 @return EFI_SUCCESS
643 @return others
644
645 **/
646 EFI_STATUS
647 GetCardType (
648 IN CARD_DATA *CardData
649 )
650 {
651 EFI_STATUS Status;
652 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
653 UINT32 Argument;
654 UINT32 ResponseData;
655 UINT32 Count;
656 BOOLEAN SDCommand8Support;
657
658
659 SDHostIo = CardData->SDHostIo;
660
661 //
662 // Reset the card
663 //
664 Status = SendCommand (
665 CardData,
666 GO_IDLE_STATE,
667 0,
668 NoData,
669 NULL,
670 0,
671 ResponseNo,
672 TIMEOUT_COMMAND,
673 NULL
674 );
675 if (EFI_ERROR (Status)) {
676 DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
677 goto Exit;
678 }
679
680 //
681 //No spec requirment, can be adjusted
682 //
683 gBS->Stall (10 * 1000);
684
685
686 //
687 // Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass
688 // MMC and SD1.1 card will fail this command
689 //
690 Argument = (VOLTAGE_27_36 << 8) | CHECK_PATTERN;
691 ResponseData = 0;
692 SDCommand8Support = FALSE;
693
694 Status = SendCommand (
695 CardData,
696 SEND_IF_COND,
697 Argument,
698 NoData,
699 NULL,
700 0,
701 ResponseR7,
702 TIMEOUT_COMMAND,
703 &ResponseData
704 );
705
706 if (EFI_ERROR (Status)) {
707 if (Status != EFI_TIMEOUT) {
708 DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, none time out error\n"));
709 goto Exit;
710 }
711 } else {
712 if (ResponseData != Argument) {
713 DEBUG((EFI_D_ERROR, "SEND_IF_COND Fail, respond data does not match send data\n"));
714 Status = EFI_DEVICE_ERROR;
715 goto Exit;
716 }
717 SDCommand8Support = TRUE;
718 }
719
720
721 Argument = 0;
722 if (SDHostIo->HostCapability.V30Support == TRUE) {
723 Argument |= BIT17 | BIT18;
724 } else if (SDHostIo->HostCapability.V33Support == TRUE) {
725 Argument |= BIT20 | BIT21;
726 }
727
728 if (SDCommand8Support) {
729 //
730 //If command SD_SEND_OP_COND sucessed, it should be set.
731 // SD 1.1 card will ignore it
732 // SD 2.0 standard card will repsond with CCS 0, SD high capacity card will respond with CCS 1
733 // CCS is BIT30 of OCR
734 Argument |= BIT30;
735 }
736
737
738 Count = 20;
739 //
740 //Only SD card will respond to this command, and spec says the card only checks condition at first ACMD41 command
741 //
742 do {
743 Status = SendAppCommand (
744 CardData,
745 SD_SEND_OP_COND,
746 Argument,
747 NoData,
748 NULL,
749 0,
750 ResponseR3,
751 TIMEOUT_COMMAND,
752 (UINT32*)&(CardData->OCRRegister)
753 );
754 if (EFI_ERROR (Status)) {
755 if ((Status == EFI_TIMEOUT) && (!SDCommand8Support)) {
756 CardData->CardType = MMCCard;
757 Status = EFI_SUCCESS;
758 DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, MMC card was identified\n"));
759 } else {
760 //
761 // Not as expected, MMC card should has no response, which means timeout.
762 // SD card should pass this command
763 //
764 DEBUG((EFI_D_ERROR, "SD_SEND_OP_COND Fail, check whether it is neither a MMC card nor a SD card\n"));
765 }
766 goto Exit;
767 }
768 //
769 //Avoid waiting if sucess. Busy bit 0 means not ready
770 //
771 if (CardData->OCRRegister.Busy == 1) {
772 break;
773 }
774
775 gBS->Stall (50 * 1000);
776 Count--;
777 if (Count == 0) {
778 DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
779 Status = EFI_TIMEOUT;
780 goto Exit;
781 }
782 } while (1);
783
784 //
785 //Check supported voltage
786 //
787 Argument = 0;
788 if (SDHostIo->HostCapability.V30Support == TRUE) {
789 if ((CardData->OCRRegister.V270_V360 & BIT2) == BIT2) {
790 Argument |= BIT17;
791 } else if ((CardData->OCRRegister.V270_V360 & BIT3) == BIT3) {
792 Argument |= BIT18;
793 }
794 } else if (SDHostIo->HostCapability.V33Support == TRUE) {
795 if ((CardData->OCRRegister.V270_V360 & BIT5) == BIT5) {
796 Argument |= BIT20;
797 } else if ((CardData->OCRRegister.V270_V360 & BIT6) == BIT6) {
798 Argument |= BIT21;
799 }
800 }
801
802 if (Argument == 0) {
803 //
804 //No matched support voltage
805 //
806 PutCardInactive (CardData);
807 DEBUG((EFI_D_ERROR, "No matched voltage for this card\n"));
808 Status = EFI_UNSUPPORTED;
809 goto Exit;
810 }
811
812 CardData->CardType = SDMemoryCard;
813 if (SDCommand8Support == TRUE) {
814 CardData->CardType = SDMemoryCard2;
815 DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above standard card was identified\n"));
816 }
817
818 if ((CardData->OCRRegister.AccessMode & BIT1) == BIT1) {
819 CardData->CardType = SDMemoryCard2High;
820 DEBUG((EFI_D_INFO, "SD_SEND_OP_COND, SD 2.0 or above high capacity card was identified\n"));
821 }
822
823
824
825 Exit:
826 return Status;
827 }
828
829 /**
830 MMC card high/low voltage selection function
831
832 @param CardData Pointer to CARD_DATA.
833
834 @retval EFI_SUCCESS
835 @retval EFI_INVALID_PARAMETER
836 @retval EFI_UNSUPPORTED
837 @retval EFI_BAD_BUFFER_SIZE
838
839 **/
840 EFI_STATUS
841 MMCCardVoltageSelection (
842 IN CARD_DATA *CardData
843 )
844 {
845 EFI_STATUS Status;
846 UINT8 Retry;
847 UINT32 TimeOut;
848
849 Status = EFI_SUCCESS;
850 //
851 //First try the high voltage, then if supported choose the low voltage
852 //
853
854 for (Retry = 0; Retry < 3; Retry++) {
855 //
856 // To bring back the normal MMC card to work
857 // after sending the SD command. Otherwise some
858 // card could not work
859
860 Status = SendCommand (
861 CardData,
862 GO_IDLE_STATE,
863 0,
864 NoData,
865 NULL,
866 0,
867 ResponseNo,
868 TIMEOUT_COMMAND,
869 NULL
870 );
871 if (EFI_ERROR (Status)) {
872 DEBUG((EFI_D_ERROR, "GO_IDLE_STATE Fail Status = 0x%x\n", Status));
873 continue;
874 }
875 //
876 //CE-ATA device needs long delay
877 //
878 gBS->Stall ((Retry + 1) * 50 * 1000);
879
880 //
881 //Get OCR register to check voltage support, first time the OCR is 0
882 //
883 Status = SendCommand (
884 CardData,
885 SEND_OP_COND,
886 0,
887 NoData,
888 NULL,
889 0,
890 ResponseR3,
891 TIMEOUT_COMMAND,
892 (UINT32*)&(CardData->OCRRegister)
893 );
894 if (!EFI_ERROR (Status)) {
895 break;
896 }
897 }
898
899 if (Retry == 3) {
900 DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
901 Status = EFI_DEVICE_ERROR;
902 goto Exit;
903 }
904
905 //
906 //TimeOut Value, 5000 * 100 * 1000 = 5 s
907 //
908 TimeOut = 5000;
909
910 do {
911 Status = SendCommand (
912 CardData,
913 SEND_OP_COND,
914 0x40300000,
915 NoData,
916 NULL,
917 0,
918 ResponseR3,
919 TIMEOUT_COMMAND,
920 (UINT32*)&(CardData->OCRRegister)
921 );
922 if (EFI_ERROR (Status)) {
923 DEBUG((EFI_D_ERROR, "SEND_OP_COND Fail Status = 0x%x\n", Status));
924 goto Exit;
925 }
926
927 gBS->Stall (1 * 1000);
928 TimeOut--;
929 if (TimeOut == 0) {
930 Status = EFI_TIMEOUT;
931 DEBUG((EFI_D_ERROR, "Card is always in busy state\n"));
932 goto Exit;
933 }
934 } while (CardData->OCRRegister.Busy != 1);
935
936 if (CardData->OCRRegister.AccessMode == 2) // eMMC Card uses Sector Addressing - High Capacity
937 {
938 DEBUG((EFI_D_INFO, "eMMC Card is High Capacity\n"));
939 CardData->CardType = MMCCardHighCap;
940 }
941
942 Exit:
943 return Status;
944
945 }
946
947 /**
948 This function set the bus and device width for MMC card
949
950 @param CardData Pointer to CARD_DATA.
951 @param Width 1, 4, 8 bits.
952
953 @retval EFI_SUCCESS
954 @retval EFI_UNSUPPORTED
955 @retval EFI_INVALID_PARAMETER
956
957 **/
958 EFI_STATUS
959 MMCCardSetBusWidth (
960 IN CARD_DATA *CardData,
961 IN UINT8 BusWidth,
962 IN BOOLEAN EnableDDRMode
963 )
964 {
965 EFI_STATUS Status;
966 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
967 SWITCH_ARGUMENT SwitchArgument;
968 UINT8 Value;
969
970 SDHostIo = CardData->SDHostIo;
971 Value = 0;
972 switch (BusWidth) {
973 case 8:
974 if (EnableDDRMode)
975 Value = 6;
976 else
977 Value = 2;
978 break;
979
980 case 4:
981 if (EnableDDRMode)
982 Value = 5;
983 else
984 Value = 1;
985 break;
986
987 case 1:
988 if (EnableDDRMode) // Bus width 1 is not supported in ddr mode
989 return EFI_UNSUPPORTED;
990 Value = 0;
991 break;
992
993 default:
994 ASSERT(0);
995 }
996
997
998 ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
999 SwitchArgument.CmdSet = 0;
1000 SwitchArgument.Value = Value;
1001 SwitchArgument.Index = (UINT32)((UINTN)
1002 (&(CardData->ExtCSDRegister.BUS_WIDTH)) - (UINTN)(&(CardData->ExtCSDRegister)));
1003 SwitchArgument.Access = WriteByte_Mode;
1004 Status = SendCommand (
1005 CardData,
1006 SWITCH,
1007 *(UINT32*)&SwitchArgument,
1008 NoData,
1009 NULL,
1010 0,
1011 ResponseR1b,
1012 TIMEOUT_COMMAND,
1013 (UINT32*)&(CardData->CardStatus)
1014 );
1015 if (!EFI_ERROR (Status)) {
1016 Status = SendCommand (
1017 CardData,
1018 SEND_STATUS,
1019 (CardData->Address << 16),
1020 NoData,
1021 NULL,
1022 0,
1023 ResponseR1,
1024 TIMEOUT_COMMAND,
1025 (UINT32*)&(CardData->CardStatus)
1026 );
1027 if (EFI_ERROR (Status)) {
1028 DEBUG((EFI_D_ERROR, "SWITCH %d bits Fail\n", BusWidth));
1029 goto Exit;
1030 } else {
1031 DEBUG((EFI_D_ERROR, "MMCCardSetBusWidth:SWITCH Card Status:0x%x\n", *(UINT32*)&(CardData->CardStatus)));
1032 Status = SDHostIo->SetBusWidth (SDHostIo, BusWidth);
1033 if (EFI_ERROR (Status)) {
1034 DEBUG((EFI_D_ERROR, "SWITCH set %d bits Fail\n", BusWidth));
1035 goto Exit;
1036 }
1037 gBS->Stall (5 * 1000);
1038 }
1039 }
1040
1041 if (!EnableDDRMode) { // CMD19 and CMD14 are illegal commands in ddr mode
1042 //if (EFI_ERROR (Status)) {
1043 // DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest: Fail to enable high speed mode\n"));
1044 // goto Exit;
1045 //}
1046
1047 Status = MMCCardBusWidthTest (CardData, BusWidth);
1048 if (EFI_ERROR (Status)) {
1049 DEBUG((EFI_D_ERROR, "MMCCardBusWidthTest %d bit Fail\n", BusWidth));
1050 goto Exit;
1051 }
1052 }
1053
1054 CardData->CurrentBusWidth = BusWidth;
1055
1056 Exit:
1057 return Status;
1058 }
1059
1060
1061 /**
1062 MMC/SD card init function
1063
1064 @param CardData Pointer to CARD_DATA.
1065
1066 @return EFI_SUCCESS
1067 @return others
1068
1069 **/
1070 EFI_STATUS
1071 MMCSDCardInit (
1072 IN CARD_DATA *CardData
1073 )
1074 {
1075 EFI_STATUS Status;
1076 EFI_SD_HOST_IO_PROTOCOL *SDHostIo;
1077 SWITCH_ARGUMENT SwitchArgument;
1078 UINT32 Data;
1079 UINT32 Argument;
1080 UINT32 nIndex;
1081 UINT8 PowerValue;
1082 BOOLEAN EnableDDRMode;
1083
1084 ASSERT(CardData != NULL);
1085 SDHostIo = CardData->SDHostIo;
1086 EnableDDRMode = FALSE;
1087
1088 CardData->CardType = UnknownCard;
1089 Status = GetCardType (CardData);
1090 if (EFI_ERROR (Status)) {
1091 goto Exit;
1092 }
1093 DEBUG((DEBUG_INFO, "CardData->CardType 0x%x\n", CardData->CardType));
1094
1095 ASSERT (CardData->CardType != UnknownCard);
1096 //
1097 //MMC, SD card need host auto stop command support
1098 //
1099 SDHostIo->EnableAutoStopCmd (SDHostIo, TRUE);
1100
1101 if (CardData->CardType == MMCCard) {
1102 Status = MMCCardVoltageSelection (CardData);
1103 if (EFI_ERROR(Status)) {
1104 goto Exit;
1105 }
1106 }
1107
1108 //
1109 // Get CID Register
1110 //
1111 Status = SendCommand (
1112 CardData,
1113 ALL_SEND_CID,
1114 0,
1115 NoData,
1116 NULL,
1117 0,
1118 ResponseR2,
1119 TIMEOUT_COMMAND,
1120 (UINT32*)&(CardData->CIDRegister)
1121 );
1122 if (EFI_ERROR (Status)) {
1123 DEBUG((EFI_D_ERROR, "ALL_SEND_CID Fail Status = 0x%x\n", Status));
1124 goto Exit;
1125 } else {
1126 // Dump out the Card ID data
1127 DEBUG((EFI_D_INFO, "Product Name: "));
1128 for ( nIndex=0; nIndex<6; nIndex++ ) {
1129 DEBUG((EFI_D_INFO, "%c", CardData->CIDRegister.PNM[nIndex]));
1130 }
1131 DEBUG((EFI_D_INFO, "\nApplication ID : %d\n", CardData->CIDRegister.OID));
1132 DEBUG((EFI_D_INFO, "Manufacturer ID: %d\n", CardData->CIDRegister.MID));
1133 DEBUG((EFI_D_INFO, "Revision ID : %d\n", CardData->CIDRegister.PRV));
1134 DEBUG((EFI_D_INFO, "Serial Number : %d\n", CardData->CIDRegister.PSN));
1135 }
1136
1137 //
1138 //SET_RELATIVE_ADDR
1139 //
1140 if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
1141 //
1142 //Hard code the RCA address
1143 //
1144 CardData->Address = 1;
1145
1146 //
1147 // Set RCA Register
1148 //
1149 Status = SendCommand (
1150 CardData,
1151 SET_RELATIVE_ADDR,
1152 (CardData->Address << 16),
1153 NoData,
1154 NULL,
1155 0,
1156 ResponseR1,
1157 TIMEOUT_COMMAND,
1158 (UINT32*)&(CardData->CardStatus)
1159 );
1160 if (EFI_ERROR (Status)) {
1161 DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
1162 goto Exit;
1163 }
1164 } else {
1165 Data = 0;
1166 Status = SendCommand (
1167 CardData,
1168 SET_RELATIVE_ADDR,
1169 0,
1170 NoData,
1171 NULL,
1172 0,
1173 ResponseR6,
1174 TIMEOUT_COMMAND,
1175 &Data
1176 );
1177 if (EFI_ERROR (Status)) {
1178 DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
1179 goto Exit;
1180 }
1181
1182 CardData->Address = (UINT16)(Data >> 16);
1183 *(UINT32*)&CardData->CardStatus = Data & 0x1FFF;
1184 CardData->CardStatus.ERROR = (Data >> 13) & 0x1;
1185 CardData->CardStatus.ILLEGAL_COMMAND = (Data >> 14) & 0x1;
1186 CardData->CardStatus.COM_CRC_ERROR = (Data >> 15) & 0x1;
1187 Status = CheckCardStatus (*(UINT32*)&CardData->CardStatus);
1188 if (EFI_ERROR (Status)) {
1189 DEBUG((EFI_D_ERROR, "SET_RELATIVE_ADDR Fail Status = 0x%x\n", Status));
1190 goto Exit;
1191 }
1192 }
1193
1194 //
1195 // Get CSD Register
1196 //
1197 Status = SendCommand (
1198 CardData,
1199 SEND_CSD,
1200 (CardData->Address << 16),
1201 NoData,
1202 NULL,
1203 0,
1204 ResponseR2,
1205 TIMEOUT_COMMAND,
1206 (UINT32*)&(CardData->CSDRegister)
1207 );
1208 if (EFI_ERROR (Status)) {
1209 DEBUG((EFI_D_ERROR, "SEND_CSD Fail Status = 0x%x\n", Status));
1210 goto Exit;
1211 }
1212
1213 DEBUG((EFI_D_INFO, "CardData->CSDRegister.SPEC_VERS = 0x%x\n", CardData->CSDRegister.SPEC_VERS));
1214 DEBUG((EFI_D_INFO, "CardData->CSDRegister.CSD_STRUCTURE = 0x%x\n", CardData->CSDRegister.CSD_STRUCTURE));
1215
1216 Status = CaculateCardParameter (CardData);
1217 if (EFI_ERROR (Status)) {
1218 goto Exit;
1219 }
1220
1221
1222 //
1223 // It is platform and hardware specific, need hadrware engineer input
1224 //
1225 if (CardData->CSDRegister.DSR_IMP == 1) {
1226 //
1227 // Default is 0x404
1228 //
1229 Status = SendCommand (
1230 CardData,
1231 SET_DSR,
1232 (DEFAULT_DSR_VALUE << 16),
1233 NoData,
1234 NULL,
1235 0,
1236 ResponseNo,
1237 TIMEOUT_COMMAND,
1238 NULL
1239 );
1240 if (EFI_ERROR (Status)) {
1241 DEBUG((EFI_D_ERROR, "SET_DSR Fail Status = 0x%x\n", Status));
1242 //
1243 // Assume can operate even fail
1244 //
1245 }
1246 }
1247 //
1248 //Change clock frequency from 400KHz to max supported when not in high speed mode
1249 //
1250 Status = SDHostIo->SetClockFrequency (SDHostIo, CardData->MaxFrequency);
1251 if (EFI_ERROR (Status)) {
1252 DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
1253 goto Exit;
1254 }
1255
1256 //
1257 //Put the card into tran state
1258 //
1259 Status = SendCommand (
1260 CardData,
1261 SELECT_DESELECT_CARD,
1262 (CardData->Address << 16),
1263 NoData,
1264 NULL,
1265 0,
1266 ResponseR1,
1267 TIMEOUT_COMMAND,
1268 (UINT32*)&(CardData->CardStatus)
1269 );
1270 if (EFI_ERROR (Status)) {
1271 DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD Fail Status = 0x%x\n", Status));
1272 goto Exit;
1273 }
1274
1275 //
1276 // No spec requirment, can be adjusted
1277 //
1278 gBS->Stall (5 * 1000);
1279 //
1280 // No need to do so
1281 //
1282 //
1283 Status = SendCommand (
1284 CardData,
1285 SEND_STATUS,
1286 (CardData->Address << 16),
1287 NoData,
1288 NULL,
1289 0,
1290 ResponseR1,
1291 TIMEOUT_COMMAND,
1292 (UINT32*)&(CardData->CardStatus)
1293 );
1294 if (EFI_ERROR (Status)) {
1295 DEBUG((EFI_D_ERROR, "SELECT_DESELECT_CARD SEND_STATUS Fail Status = 0x%x\n", Status));
1296 goto Exit;
1297 }
1298 //
1299 //if the SPEC_VERS indicates a version 4.0 or higher
1300 //The card is a high speed card and support Switch
1301 //and Send_ext_csd command
1302 //otherwise it is an old card
1303 //
1304
1305 if (CardData->CardType == MMCCard || CardData->CardType == MMCCardHighCap) {
1306 //
1307 //Only V4.0 and above supports more than 1 bits and high speed
1308 //
1309 if (CardData->CSDRegister.SPEC_VERS >= 4) {
1310 //
1311 //Get ExtCSDRegister
1312 //
1313 Status = SendCommand (
1314 CardData,
1315 SEND_EXT_CSD,
1316 0x0,
1317 InData,
1318 CardData->AlignedBuffer,
1319 sizeof (EXT_CSD),
1320 ResponseR1,
1321 TIMEOUT_DATA,
1322 (UINT32*)&(CardData->CardStatus)
1323 );
1324 if (EFI_ERROR (Status)) {
1325 DEBUG((EFI_D_ERROR, "SEND_EXT_CSD Fail Status = 0x%x\n", Status));
1326 goto Exit;
1327 }
1328
1329 CopyMem (&(CardData->ExtCSDRegister), CardData->AlignedBuffer, sizeof (EXT_CSD));
1330
1331 //
1332 // Recaculate the block number for >2G MMC card
1333 //
1334 Data = (CardData->ExtCSDRegister.SEC_COUNT[0]) |
1335 (CardData->ExtCSDRegister.SEC_COUNT[1] << 8) |
1336 (CardData->ExtCSDRegister.SEC_COUNT[2] << 16) |
1337 (CardData->ExtCSDRegister.SEC_COUNT[3] << 24);
1338
1339 if (Data != 0) {
1340 CardData->BlockNumber = Data;
1341 }
1342 DEBUG((DEBUG_INFO, "CardData->BlockNumber %d\n", Data));
1343 DEBUG((EFI_D_ERROR, "CardData->ExtCSDRegister.CARD_TYPE -> %d\n", (UINTN)CardData->ExtCSDRegister.CARD_TYPE));
1344 if ((CardData->ExtCSDRegister.CARD_TYPE & BIT2)||
1345 (CardData->ExtCSDRegister.CARD_TYPE & BIT3)) {
1346 //DEBUG((DEBUG_INFO, "To enable DDR mode\n"));
1347 //EnableDDRMode = TRUE;
1348 }
1349 //
1350 // Check current chipset capability and the plugged-in card
1351 // whether supports HighSpeed
1352 //
1353 if (SDHostIo->HostCapability.HighSpeedSupport) {
1354
1355 //
1356 //Change card timing to high speed interface timing
1357 //
1358 ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
1359 SwitchArgument.CmdSet = 0;
1360 SwitchArgument.Value = 1;
1361 SwitchArgument.Index = (UINT32)((UINTN)
1362 (&(CardData->ExtCSDRegister.HS_TIMING)) - (UINTN)(&(CardData->ExtCSDRegister)));
1363 SwitchArgument.Access = WriteByte_Mode;
1364 Status = SendCommand (
1365 CardData,
1366 SWITCH,
1367 *(UINT32*)&SwitchArgument,
1368 NoData,
1369 NULL,
1370 0,
1371 ResponseR1b,
1372 TIMEOUT_COMMAND,
1373 (UINT32*)&(CardData->CardStatus)
1374 );
1375 if (EFI_ERROR (Status)) {
1376 DEBUG((EFI_D_ERROR, "MMCSDCardInit:SWITCH frequency Fail Status = 0x%x\n", Status));
1377 }
1378
1379 gBS->Stall (5 * 1000);
1380
1381
1382 if (!EFI_ERROR (Status)) {
1383 Status = SendCommand (
1384 CardData,
1385 SEND_STATUS,
1386 (CardData->Address << 16),
1387 NoData,
1388 NULL,
1389 0,
1390 ResponseR1,
1391 TIMEOUT_COMMAND,
1392 (UINT32*)&(CardData->CardStatus)
1393 );
1394 if (!EFI_ERROR (Status)) {
1395 if (EnableDDRMode) {
1396 DEBUG((EFI_D_ERROR, "Enable ddr mode on host controller\n"));
1397 SDHostIo->SetDDRMode (SDHostIo, TRUE);
1398 } else {
1399 DEBUG((EFI_D_ERROR, "Enable high speed mode on host controller\n"));
1400 SDHostIo->SetHighSpeedMode (SDHostIo, TRUE);
1401 }
1402 //
1403 // Change host clock to support high speed and enable chispet to
1404 // support speed
1405 //
1406 if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
1407 Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP_HIGH);
1408 } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
1409 Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_MMC_PP);
1410 } else {
1411 Status = EFI_UNSUPPORTED;
1412 }
1413 if (EFI_ERROR (Status)) {
1414 DEBUG((EFI_D_ERROR, "MMCSDCardInit:Fail to SetClockFrequency \n"));
1415 goto Exit;
1416 }
1417 //
1418 // It seems no need to stall after changing bus freqeuncy.
1419 // It is said that the freqeuncy can be changed at any time. Just appends 8 clocks after command.
1420 // But SetClock alreay has delay.
1421 //
1422 }
1423 }
1424
1425 }
1426
1427
1428
1429 //
1430 // Prefer wide bus width for performance
1431 //
1432 //
1433 // Set to BusWidth bits mode, only version 4.0 or above support more than 1 bits
1434 //
1435 if (SDHostIo->HostCapability.BusWidth8 == TRUE) {
1436 Status = MMCCardSetBusWidth (CardData, 8, EnableDDRMode);
1437 if (EFI_ERROR (Status)) {
1438 //
1439 // CE-ATA may support 8 bits and 4 bits, but has no software method for detection
1440 //
1441 Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
1442 if (EFI_ERROR (Status)) {
1443 goto Exit;
1444 }
1445 }
1446 } else if (SDHostIo->HostCapability.BusWidth4 == TRUE) {
1447 Status = MMCCardSetBusWidth (CardData, 4, EnableDDRMode);
1448 if (EFI_ERROR (Status)) {
1449 goto Exit;
1450 }
1451 }
1452
1453 PowerValue = 0;
1454
1455 if (CardData->CurrentBusWidth == 8) {
1456 if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
1457 PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
1458 PowerValue = PowerValue >> 4;
1459 } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
1460 PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
1461 PowerValue = PowerValue >> 4;
1462 }
1463 } else if (CardData->CurrentBusWidth == 4) {
1464 if ((CardData->ExtCSDRegister.CARD_TYPE & BIT1) != 0) {
1465 PowerValue = CardData->ExtCSDRegister.PWR_CL_52_360;
1466 PowerValue = PowerValue & 0xF;
1467 } else if ((CardData->ExtCSDRegister.CARD_TYPE & BIT0) != 0) {
1468 PowerValue = CardData->ExtCSDRegister.PWR_CL_26_360;
1469 PowerValue = PowerValue & 0xF;
1470 }
1471 }
1472
1473 if (PowerValue != 0) {
1474 //
1475 //Update Power Class
1476 //
1477 ZeroMem(&SwitchArgument, sizeof (SWITCH_ARGUMENT));
1478 SwitchArgument.CmdSet = 0;
1479 SwitchArgument.Value = PowerValue;
1480 SwitchArgument.Index = (UINT32)((UINTN)
1481 (&(CardData->ExtCSDRegister.POWER_CLASS)) - (UINTN)(&(CardData->ExtCSDRegister)));
1482 SwitchArgument.Access = WriteByte_Mode;
1483 Status = SendCommand (
1484 CardData,
1485 SWITCH,
1486 *(UINT32*)&SwitchArgument,
1487 NoData,
1488 NULL,
1489 0,
1490 ResponseR1b,
1491 TIMEOUT_COMMAND,
1492 (UINT32*)&(CardData->CardStatus)
1493 );
1494 if (!EFI_ERROR (Status)) {
1495 Status = SendCommand (
1496 CardData,
1497 SEND_STATUS,
1498 (CardData->Address << 16),
1499 NoData,
1500 NULL,
1501 0,
1502 ResponseR1,
1503 TIMEOUT_COMMAND,
1504 (UINT32*)&(CardData->CardStatus)
1505 );
1506 if (EFI_ERROR (Status)) {
1507 DEBUG((EFI_D_ERROR, "SWITCH Power Class Fail Status = 0x%x\n", Status));
1508 }
1509 //gBS->Stall (10 * 1000);
1510 }
1511 }
1512
1513
1514
1515 } else {
1516
1517
1518 DEBUG((EFI_D_ERROR, "MMC Card version %d only supportes 1 bits at lower transfer speed\n",CardData->CSDRegister.SPEC_VERS));
1519 }
1520 } else {
1521 //
1522 // Pin 1, at power up this line has a 50KOhm pull up enabled in the card.
1523 // This pull-up should be disconnected by the user, during regular data transfer,
1524 // with SET_CLR_CARD_DETECT (ACMD42) command
1525 //
1526 Status = SendAppCommand (
1527 CardData,
1528 SET_CLR_CARD_DETECT,
1529 0,
1530 NoData,
1531 NULL,
1532 0,
1533 ResponseR1,
1534 TIMEOUT_COMMAND,
1535 (UINT32*)&(CardData->CardStatus)
1536 );
1537 if (EFI_ERROR (Status)) {
1538 DEBUG((EFI_D_ERROR, "SET_CLR_CARD_DETECT Fail Status = 0x%x\n", Status));
1539 goto Exit;
1540 }
1541
1542 /*
1543 //
1544 // Don't rely on SCR and SD status, some cards have unexpected SCR.
1545 // It only sets private section, the other bits are 0
1546 // such as Sandisk Ultra II 4.0G, KinSton mini SD 128M, Toshiba 2.0GB
1547 // Some card even fail this command, KinSton SD 4GB
1548 //
1549 Status = SendAppCommand (
1550 CardData,
1551 SEND_SCR,
1552 0,
1553 InData,
1554 (UINT8*)&(CardData->SCRRegister),
1555 sizeof(SCR),
1556 ResponseR1,
1557 TIMEOUT_COMMAND,
1558 (UINT32*)&(CardData->CardStatus)
1559 );
1560 if (EFI_ERROR (Status)) {
1561 goto Exit;
1562 }
1563
1564 //
1565 // SD memory card at least supports 1 and 4 bits.
1566 //
1567 // ASSERT ((CardData->SCRRegister.SD_BUS_WIDTH & (BIT0 | BIT2)) == (BIT0 | BIT2));
1568 */
1569
1570 //
1571 // Set Bus Width to 4
1572 //
1573 Status = SendAppCommand (
1574 CardData,
1575 SET_BUS_WIDTH,
1576 SD_BUS_WIDTH_4,
1577 NoData,
1578 NULL,
1579 0,
1580 ResponseR1,
1581 TIMEOUT_COMMAND,
1582 (UINT32*)&(CardData->CardStatus)
1583 );
1584 if (EFI_ERROR (Status)) {
1585 DEBUG((EFI_D_ERROR, "SET_BUS_WIDTH 4 bits Fail Status = 0x%x\n", Status));
1586 goto Exit;
1587 }
1588
1589 Status = SDHostIo->SetBusWidth (SDHostIo, 4);
1590 if (EFI_ERROR (Status)) {
1591 goto Exit;
1592 }
1593 CardData->CurrentBusWidth = 4;
1594
1595
1596 if ((SDHostIo->HostCapability.HighSpeedSupport == FALSE) ||
1597 ((CardData->CSDRegister.CCC & BIT10) != BIT10)) {
1598 //
1599 // Host must support high speed
1600 // Card must support Switch function
1601 //
1602 goto Exit;
1603 }
1604
1605 //
1606 //Mode = 0, group 1, function 1, check operation
1607 //
1608 Argument = 0xFFFF01;
1609 ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
1610
1611 Status = SendCommand (
1612 CardData,
1613 SWITCH_FUNC,
1614 Argument,
1615 InData,
1616 CardData->AlignedBuffer,
1617 sizeof (SWITCH_STATUS),
1618 ResponseR1,
1619 TIMEOUT_COMMAND,
1620 (UINT32*)&(CardData->CardStatus)
1621 );
1622 if (EFI_ERROR (Status)) {
1623 goto Exit;
1624 }
1625 CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
1626
1627 if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
1628 ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
1629 //
1630 // 1. SD 1.1 card does not suppport busy bit
1631 // 2. Ready state
1632 //
1633 //
1634
1635 //
1636 //Mode = 1, group 1, function 1, BIT31 set means set mode
1637 //
1638 Argument = 0xFFFF01 | BIT31;
1639 ZeroMem (&CardData->SwitchStatus, sizeof (SWITCH_STATUS));
1640
1641 Status = SendCommand (
1642 CardData,
1643 SWITCH_FUNC,
1644 Argument,
1645 InData,
1646 CardData->AlignedBuffer,
1647 sizeof (SWITCH_STATUS),
1648 ResponseR1,
1649 TIMEOUT_COMMAND,
1650 (UINT32*)&(CardData->CardStatus)
1651 );
1652 if (EFI_ERROR (Status)) {
1653 goto Exit;
1654 }
1655 CopyMem (&(CardData->SwitchStatus), CardData->AlignedBuffer, sizeof (SWITCH_STATUS));
1656
1657 if ((CardData->SwitchStatus.DataStructureVersion == 0x0) ||
1658 ((CardData->SwitchStatus.Group1BusyStatus & BIT1) != BIT1)) {
1659 //
1660 // 1. SD 1.1 card does not suppport busy bit
1661 // 2. Ready state
1662 //
1663
1664 //
1665 // 8 clocks, (1/ 25M) * 8 ==> 320 us, so 1ms > 0.32 ms
1666 //
1667 gBS->Stall (1000);
1668
1669 //
1670 //Change host clock
1671 //
1672 Status = SDHostIo->SetClockFrequency (SDHostIo, FREQUENCY_SD_PP_HIGH);
1673 if (EFI_ERROR (Status)) {
1674 goto Exit;
1675 }
1676
1677 }
1678 }
1679 }
1680 if (!((CardData->ExtCSDRegister.CARD_TYPE & BIT2) ||
1681 (CardData->ExtCSDRegister.CARD_TYPE & BIT3))) {
1682
1683 //
1684 // Set Block Length, to improve compatibility in case of some cards
1685 //
1686 Status = SendCommand (
1687 CardData,
1688 SET_BLOCKLEN,
1689 512,
1690 NoData,
1691 NULL,
1692 0,
1693 ResponseR1,
1694 TIMEOUT_COMMAND,
1695 (UINT32*)&(CardData->CardStatus)
1696 );
1697 if (EFI_ERROR (Status)) {
1698 DEBUG((EFI_D_ERROR, "SET_BLOCKLEN Fail Status = 0x%x\n", Status));
1699 goto Exit;
1700 }
1701 }
1702 SDHostIo->SetBlockLength (SDHostIo, 512);
1703
1704
1705 Exit:
1706 return Status;
1707 }
1708