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