3 Copyright (c) 2008-2009, Apple Inc. All rights reserved.
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
19 EFI_BLOCK_IO_MEDIA MMCHSMedia
= {
20 SIGNATURE_32('s','d','i','o'), // MediaId
21 FALSE
, // RemovableMedia
23 TRUE
, // LogicalPartition
25 FALSE
, // WriteCaching
33 VENDOR_DEVICE_PATH Mmc
;
37 MMCHS_DEVICE_PATH gMmcHsDevicePath
=
42 (UINT8
)(sizeof(VENDOR_DEVICE_PATH
)),
43 (UINT8
)((sizeof(VENDOR_DEVICE_PATH
)) >> 8),
44 0xb615f1f5, 0x5088, 0x43cd, 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00
48 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 sizeof (EFI_DEVICE_PATH_PROTOCOL
),
55 EMBEDDED_EXTERNAL_DEVICE
*gTPS65950
;
70 gCardInfo
->CIDData
.MDT
= ((Response0
>> 8) & 0xFFF);
71 gCardInfo
->CIDData
.PSN
= (((Response0
>> 24) & 0xFF) | ((Response1
& 0xFFFFFF) << 8));
72 gCardInfo
->CIDData
.PRV
= ((Response1
>> 24) & 0xFF);
73 gCardInfo
->CIDData
.PNM
[4] = ((Response2
) & 0xFF);
74 gCardInfo
->CIDData
.PNM
[3] = ((Response2
>> 8) & 0xFF);
75 gCardInfo
->CIDData
.PNM
[2] = ((Response2
>> 16) & 0xFF);
76 gCardInfo
->CIDData
.PNM
[1] = ((Response2
>> 24) & 0xFF);
77 gCardInfo
->CIDData
.PNM
[0] = ((Response3
) & 0xFF);
78 gCardInfo
->CIDData
.OID
= ((Response3
>> 8) & 0xFFFF);
79 gCardInfo
->CIDData
.MID
= ((Response3
>> 24) & 0xFF);
84 UpdateMMCHSClkFrequency (
88 //Set Clock enable to 0x0 to not provide the clock to the card
89 MmioAnd32(MMCHS_SYSCTL
, ~CEN
);
91 //Set new clock frequency.
92 MmioAndThenOr32(MMCHS_SYSCTL
, ~CLKD_MASK
, NewCLKD
<< 6);
94 //Poll till Internal Clock Stable
95 while ((MmioRead32(MMCHS_SYSCTL
) & ICS_MASK
) != ICS
);
97 //Set Clock enable to 0x1 to provide the clock to the card
98 MmioOr32(MMCHS_SYSCTL
, CEN
);
105 UINTN CmdInterruptEnableVal
,
110 UINTN RetryCount
= 0;
112 //Check if command line is in use or not. Poll till command line is available.
113 while ((MmioRead32(MMCHS_PSTATE
) & DATI_MASK
) == DATI_NOT_ALLOWED
);
115 //Provide the block size.
116 MmioWrite32(MMCHS_BLK
, BLEN_512BYTES
);
118 //Setting Data timeout counter value to max value.
119 MmioAndThenOr32(MMCHS_SYSCTL
, ~DTO_MASK
, DTO_VAL
);
121 //Clear Status register.
122 MmioWrite32(MMCHS_STAT
, 0xFFFFFFFF);
124 //Set command argument register
125 MmioWrite32(MMCHS_ARG
, CmdArgument
);
127 //Enable interrupt enable events to occur
128 MmioWrite32(MMCHS_IE
, CmdInterruptEnableVal
);
131 MmioWrite32(MMCHS_CMD
, Cmd
);
133 //Check for the command status.
134 while (RetryCount
< MAX_RETRY_COUNT
) {
136 MmcStatus
= MmioRead32(MMCHS_STAT
);
137 } while (MmcStatus
== 0);
139 //Read status of command response
140 if ((MmcStatus
& ERRI
) != 0) {
142 //Perform soft-reset for mmci_cmd line.
143 MmioOr32(MMCHS_SYSCTL
, SRC
);
144 while ((MmioRead32(MMCHS_SYSCTL
) & SRC
));
146 DEBUG ((EFI_D_INFO
, "MmcStatus: %x\n", MmcStatus
));
147 return EFI_DEVICE_ERROR
;
150 //Check if command is completed.
151 if ((MmcStatus
& CC
) == CC
) {
152 MmioWrite32(MMCHS_STAT
, CC
);
159 if (RetryCount
== MAX_RETRY_COUNT
) {
168 GetBlockInformation (
173 CSD_SDV2
*CsdSDV2Data
;
176 if (gCardInfo
->CardType
== SD_CARD_2_HIGH
) {
177 CsdSDV2Data
= (CSD_SDV2
*)&gCardInfo
->CSDData
;
179 //Populate BlockSize.
180 *BlockSize
= (0x1UL
<< CsdSDV2Data
->READ_BL_LEN
);
182 //Calculate Total number of blocks.
183 CardSize
= CsdSDV2Data
->C_SIZELow16
| (CsdSDV2Data
->C_SIZEHigh6
<< 2);
184 *NumBlocks
= ((CardSize
+ 1) * 1024);
186 //Populate BlockSize.
187 *BlockSize
= (0x1UL
<< gCardInfo
->CSDData
.READ_BL_LEN
);
189 //Calculate Total number of blocks.
190 CardSize
= gCardInfo
->CSDData
.C_SIZELow2
| (gCardInfo
->CSDData
.C_SIZEHigh10
<< 2);
191 *NumBlocks
= (CardSize
+ 1) * (1 << (gCardInfo
->CSDData
.C_SIZE_MULT
+ 2));
194 //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
195 if (*BlockSize
> 512) {
196 *NumBlocks
= MultU64x32(*NumBlocks
, *BlockSize
/2);
200 DEBUG ((EFI_D_INFO
, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo
->CardType
, *BlockSize
, *NumBlocks
));
206 UINTN
*ClockFrequencySelect
209 UINT8 MaxDataTransferRate
;
210 UINTN TransferRateValue
= 0;
211 UINTN TimeValue
= 0 ;
214 MaxDataTransferRate
= gCardInfo
->CSDData
.TRAN_SPEED
;
216 //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
217 switch (MaxDataTransferRate
& 0x7) {
219 TransferRateValue
= 100 * 1000;
223 TransferRateValue
= 1 * 1000 * 1000;
227 TransferRateValue
= 10 * 1000 * 1000;
231 TransferRateValue
= 100 * 1000 * 1000;
235 DEBUG((EFI_D_ERROR
, "Invalid parameter.\n"));
239 //Calculate Time value (Bits 6:3 of TRAN_SPEED)
240 switch ((MaxDataTransferRate
>> 3) & 0xF) {
302 DEBUG((EFI_D_ERROR
, "Invalid parameter.\n"));
306 Frequency
= TransferRateValue
* TimeValue
/10;
308 //Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
309 *ClockFrequencySelect
= ((MMC_REFERENCE_CLK
/Frequency
) + 1);
311 DEBUG ((EFI_D_INFO
, "MaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", MaxDataTransferRate
, Frequency
/1000, *ClockFrequencySelect
));
316 GetCardConfigurationData (
322 UINTN ClockFrequencySelect
;
324 //Calculate BlockSize and Total number of blocks in the detected card.
325 GetBlockInformation(&BlockSize
, &NumBlocks
);
326 gCardInfo
->BlockSize
= BlockSize
;
327 gCardInfo
->NumBlocks
= NumBlocks
;
329 //Calculate Card clock divider value.
330 CalculateCardCLKD(&ClockFrequencySelect
);
331 gCardInfo
->ClockFrequencySelect
= ClockFrequencySelect
;
343 //Select Device group to belong to P1 device group in Power IC.
345 Status
= gTPS65950
->Write(gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VMMC1_DEV_GRP
), 1, &Data
);
346 ASSERT_EFI_ERROR(Status
);
348 //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
350 Status
= gTPS65950
->Write(gTPS65950
, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4
, VMMC1_DEDICATED_REG
), 1, &Data
);
351 ASSERT_EFI_ERROR(Status
);
353 //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
354 MmioOr32(CONTROL_PBIAS_LITE
, (PBIASLITEVMODE0
| PBIASLITEPWRDNZ0
| PBIASSPEEDCTRL0
| PBIASLITEVMODE1
| PBIASLITEWRDNZ1
));
356 //Software reset of the MMCHS host controller.
357 MmioWrite32(MMCHS_SYSCONFIG
, SOFTRESET
);
359 while ((MmioRead32(MMCHS_SYSSTATUS
) & RESETDONE_MASK
) != RESETDONE
);
361 //Soft reset for all.
362 MmioWrite32(MMCHS_SYSCTL
, SRA
);
364 while ((MmioRead32(MMCHS_SYSCTL
) & SRA
) != 0x0);
366 //Voltage capabilities initialization. Activate VS18 and VS30.
367 MmioOr32(MMCHS_CAPA
, (VS30
| VS18
));
369 //Wakeup configuration
370 MmioOr32(MMCHS_SYSCONFIG
, ENAWAKEUP
);
371 MmioOr32(MMCHS_HCTL
, IWE
);
373 //MMCHS Controller default initialization
374 MmioOr32(MMCHS_CON
, (OD
| DW8_1_4_BIT
| CEATA_OFF
));
376 MmioWrite32(MMCHS_HCTL
, (SDVS_3_0_V
| DTW_1_BIT
| SDBP_OFF
));
378 //Enable internal clock
379 MmioOr32(MMCHS_SYSCTL
, ICE
);
381 //Set the clock frequency to 80KHz.
382 UpdateMMCHSClkFrequency(CLKD_80KHZ
);
384 //Enable SD bus power.
385 MmioOr32(MMCHS_HCTL
, (SDBP_ON
));
387 //Poll till SD bus power bit is set.
388 while ((MmioRead32(MMCHS_HCTL
) & SDBP_MASK
) != SDBP_ON
);
395 PerformCardIdenfication (
400 UINTN CmdArgument
= 0;
402 UINTN RetryCount
= 0;
403 BOOLEAN SDCmd8Supported
= FALSE
;
406 MmioWrite32(MMCHS_IE
, (BADA_EN
| CERR_EN
| DEB_EN
| DCRC_EN
| DTO_EN
| CIE_EN
|
407 CEB_EN
| CCRC_EN
| CTO_EN
| BRR_EN
| BWR_EN
| TC_EN
| CC_EN
));
409 //Controller INIT procedure start.
410 MmioOr32(MMCHS_CON
, INIT
);
411 MmioWrite32(MMCHS_CMD
, 0x00000000);
412 while (!(MmioRead32(MMCHS_STAT
) & CC
));
417 //Set CC bit to 0x1 to clear the flag
418 MmioOr32(MMCHS_STAT
, CC
);
420 //Retry INIT procedure.
421 MmioWrite32(MMCHS_CMD
, 0x00000000);
422 while (!(MmioRead32(MMCHS_STAT
) & CC
));
424 //End initialization sequence
425 MmioAnd32(MMCHS_CON
, ~INIT
);
427 MmioOr32(MMCHS_HCTL
, (SDVS_3_0_V
| DTW_1_BIT
| SDBP_ON
));
429 //Change clock frequency to 400KHz to fit protocol
430 UpdateMMCHSClkFrequency(CLKD_400KHZ
);
432 MmioOr32(MMCHS_CON
, OD
);
435 Status
= SendCmd(CMD0
, CMD0_INT_EN
, CmdArgument
);
436 if (EFI_ERROR(Status
)) {
437 DEBUG ((EFI_D_ERROR
, "Cmd0 fails.\n"));
441 DEBUG ((EFI_D_INFO
, "CMD0 response: %x\n", MmioRead32(MMCHS_RSP10
)));
444 Status
= SendCmd(CMD5
, CMD5_INT_EN
, CmdArgument
);
445 if (Status
== EFI_SUCCESS
) {
446 DEBUG ((EFI_D_ERROR
, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
447 DEBUG ((EFI_D_INFO
, "CMD5 response: %x\n", MmioRead32(MMCHS_RSP10
)));
448 //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
449 return EFI_UNSUPPORTED
;
451 DEBUG ((EFI_D_INFO
, "CMD5 fails. Not an SDIO card.\n"));
454 MmioOr32(MMCHS_SYSCTL
, SRC
);
456 while ((MmioRead32(MMCHS_SYSCTL
) & SRC
));
458 //Send CMD8 command. (New v2.00 command for Voltage check)
459 //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
460 //MMC & SD1.1 card will fail this command.
461 CmdArgument
= CMD8_ARG
;
462 Status
= SendCmd(CMD8
, CMD8_INT_EN
, CmdArgument
);
463 if (Status
== EFI_SUCCESS
) {
464 Response
= MmioRead32(MMCHS_RSP10
);
465 DEBUG ((EFI_D_INFO
, "CMD8 success. CMD8 response: %x\n", Response
));
466 if (Response
!= CmdArgument
) {
467 return EFI_DEVICE_ERROR
;
469 DEBUG ((EFI_D_INFO
, "Card is SD2.0\n"));
470 SDCmd8Supported
= TRUE
; //Supports high capacity.
472 DEBUG ((EFI_D_INFO
, "CMD8 fails. Not an SD2.0 card.\n"));
475 MmioOr32(MMCHS_SYSCTL
, SRC
);
477 while ((MmioRead32(MMCHS_SYSCTL
) & SRC
));
479 //Poll till card is busy
480 while (RetryCount
< MAX_RETRY_COUNT
) {
481 //Send CMD55 command.
483 Status
= SendCmd(CMD55
, CMD55_INT_EN
, CmdArgument
);
484 if (Status
== EFI_SUCCESS
) {
485 DEBUG ((EFI_D_INFO
, "CMD55 success. CMD55 response: %x\n", MmioRead32(MMCHS_RSP10
)));
486 gCardInfo
->CardType
= SD_CARD
;
488 DEBUG ((EFI_D_INFO
, "CMD55 fails.\n"));
489 gCardInfo
->CardType
= MMC_CARD
;
492 //Send appropriate command for the card type which got detected.
493 if (gCardInfo
->CardType
== SD_CARD
) {
494 CmdArgument
= ((UINTN
*) &(gCardInfo
->OCRData
))[0];
497 if (SDCmd8Supported
) {
501 Status
= SendCmd(ACMD41
, ACMD41_INT_EN
, CmdArgument
);
502 if (EFI_ERROR(Status
)) {
503 DEBUG ((EFI_D_INFO
, "ACMD41 fails.\n"));
506 ((UINT32
*) &(gCardInfo
->OCRData
))[0] = MmioRead32(MMCHS_RSP10
);
507 DEBUG ((EFI_D_INFO
, "SD card detected. ACMD41 OCR: %x\n", ((UINT32
*) &(gCardInfo
->OCRData
))[0]));
508 } else if (gCardInfo
->CardType
== MMC_CARD
) {
510 Status
= SendCmd(CMD1
, CMD1_INT_EN
, CmdArgument
);
511 if (EFI_ERROR(Status
)) {
512 DEBUG ((EFI_D_INFO
, "CMD1 fails.\n"));
515 Response
= MmioRead32(MMCHS_RSP10
);
516 DEBUG ((EFI_D_INFO
, "MMC card detected.. CMD1 response: %x\n", Response
));
518 //NOTE: For now, I am skipping this since I only have an SD card.
519 //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
520 return EFI_UNSUPPORTED
; //For now, MMC is not supported.
523 //Poll the card until it is out of its power-up sequence.
524 if (gCardInfo
->OCRData
.Busy
== 1) {
526 if (SDCmd8Supported
) {
527 gCardInfo
->CardType
= SD_CARD_2
;
530 //Card is ready. Check CCS (Card capacity status) bit (bit#30).
531 //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
532 if (gCardInfo
->OCRData
.AccessMode
& BIT1
) {
533 gCardInfo
->CardType
= SD_CARD_2_HIGH
;
534 DEBUG ((EFI_D_INFO
, "High capacity card.\n"));
536 DEBUG ((EFI_D_INFO
, "Standard capacity card.\n"));
546 if (RetryCount
== MAX_RETRY_COUNT
) {
547 DEBUG ((EFI_D_ERROR
, "Timeout error. RetryCount: %d\n", RetryCount
));
553 Status
= SendCmd(CMD2
, CMD2_INT_EN
, CmdArgument
);
554 if (EFI_ERROR(Status
)) {
555 DEBUG ((EFI_D_ERROR
, "CMD2 fails. Status: %x\n", Status
));
559 DEBUG ((EFI_D_INFO
, "CMD2 response: %x %x %x %x\n", MmioRead32(MMCHS_RSP10
), MmioRead32(MMCHS_RSP32
), MmioRead32(MMCHS_RSP54
), MmioRead32(MMCHS_RSP76
)));
561 //Parse CID register data.
562 ParseCardCIDData(MmioRead32(MMCHS_RSP10
), MmioRead32(MMCHS_RSP32
), MmioRead32(MMCHS_RSP54
), MmioRead32(MMCHS_RSP76
));
566 Status
= SendCmd(CMD3
, CMD3_INT_EN
, CmdArgument
);
567 if (EFI_ERROR(Status
)) {
568 DEBUG ((EFI_D_ERROR
, "CMD3 fails. Status: %x\n", Status
));
572 //Set RCA for the detected card. RCA is CMD3 response.
573 gCardInfo
->RCA
= (MmioRead32(MMCHS_RSP10
) >> 16);
574 DEBUG ((EFI_D_INFO
, "CMD3 response: RCA %x\n", gCardInfo
->RCA
));
576 //MMC Bus setting change after card identification.
577 MmioAnd32(MMCHS_CON
, ~OD
);
578 MmioOr32(MMCHS_HCTL
, SDVS_3_0_V
);
579 UpdateMMCHSClkFrequency(CLKD_400KHZ
); //Set the clock frequency to 400KHz.
586 GetCardSpecificData (
593 //Send CMD9 to retrieve CSD.
594 CmdArgument
= gCardInfo
->RCA
<< 16;
595 Status
= SendCmd(CMD9
, CMD9_INT_EN
, CmdArgument
);
596 if (EFI_ERROR(Status
)) {
597 DEBUG ((EFI_D_ERROR
, "CMD9 fails. Status: %x\n", Status
));
601 //Populate 128-bit CSD register data.
602 ((UINT32
*)&(gCardInfo
->CSDData
))[0] = MmioRead32(MMCHS_RSP10
);
603 ((UINT32
*)&(gCardInfo
->CSDData
))[1] = MmioRead32(MMCHS_RSP32
);
604 ((UINT32
*)&(gCardInfo
->CSDData
))[2] = MmioRead32(MMCHS_RSP54
);
605 ((UINT32
*)&(gCardInfo
->CSDData
))[3] = MmioRead32(MMCHS_RSP76
);
607 DEBUG ((EFI_D_INFO
, "CMD9 response: %x %x %x %x\n", MmioRead32(MMCHS_RSP10
), MmioRead32(MMCHS_RSP32
), MmioRead32(MMCHS_RSP54
), MmioRead32(MMCHS_RSP76
)));
609 //Calculate total number of blocks and max. data transfer rate supported by the detected card.
610 GetCardConfigurationData();
612 //Change MMCHS clock frequency to what detected card can support.
613 UpdateMMCHSClkFrequency(gCardInfo
->ClockFrequencySelect
);
620 PerformCardConfiguration (
624 UINTN CmdArgument
= 0;
628 CmdArgument
= gCardInfo
->RCA
<< 16;
629 Status
= SendCmd(CMD7
, CMD7_INT_EN
, CmdArgument
);
630 if (EFI_ERROR(Status
)) {
631 DEBUG ((EFI_D_ERROR
, "CMD7 fails. Status: %x\n", Status
));
635 //Send CMD16 to set the block length
636 CmdArgument
= gCardInfo
->BlockSize
;
637 Status
= SendCmd(CMD16
, CMD16_INT_EN
, CmdArgument
);
638 if (EFI_ERROR(Status
)) {
639 DEBUG ((EFI_D_ERROR
, "CMD16 fails. Status: %x\n", Status
));
649 IN EFI_BLOCK_IO_PROTOCOL
*This
,
654 UINTN
*DataBuffer
= Buffer
;
655 UINTN DataSize
= This
->Media
->BlockSize
/4;
657 UINTN RetryCount
= 0;
659 //Check controller status to make sure there is no error.
660 while (RetryCount
< MAX_RETRY_COUNT
) {
663 MmcStatus
= MmioRead32(MMCHS_STAT
);
664 } while(MmcStatus
== 0);
666 //Check if Buffer read ready (BRR) bit is set?
667 if (MmcStatus
& BRR
) {
670 MmioOr32(MMCHS_STAT
, BRR
);
672 //Read block worth of data.
673 for (Count
= 0; Count
< DataSize
; Count
++) {
674 *DataBuffer
++ = MmioRead32(MMCHS_DATA
);
681 if (RetryCount
== MAX_RETRY_COUNT
) {
691 IN EFI_BLOCK_IO_PROTOCOL
*This
,
696 UINTN
*DataBuffer
= Buffer
;
697 UINTN DataSize
= This
->Media
->BlockSize
/4;
699 UINTN RetryCount
= 0;
701 //Check controller status to make sure there is no error.
702 while (RetryCount
< MAX_RETRY_COUNT
) {
705 MmcStatus
= MmioRead32(MMCHS_STAT
);
706 } while(MmcStatus
== 0);
708 //Check if Buffer write ready (BWR) bit is set?
709 if (MmcStatus
& BWR
) {
712 MmioOr32(MMCHS_STAT
, BWR
);
714 //Write block worth of data.
715 for (Count
= 0; Count
< DataSize
; Count
++) {
716 MmioWrite32(MMCHS_DATA
, *DataBuffer
++);
724 if (RetryCount
== MAX_RETRY_COUNT
) {
734 IN EFI_BLOCK_IO_PROTOCOL
*This
,
736 IN OPERATION_TYPE OperationType
741 UINTN RetryCount
= 0;
743 //Read or Write data.
744 if (OperationType
== READ
) {
745 Status
= ReadBlockData(This
, Buffer
);
746 if (EFI_ERROR(Status
)) {
747 DEBUG((EFI_D_ERROR
, "ReadBlockData fails.\n"));
750 } else if (OperationType
== WRITE
) {
751 Status
= WriteBlockData(This
, Buffer
);
752 if (EFI_ERROR(Status
)) {
753 DEBUG((EFI_D_ERROR
, "WriteBlockData fails.\n"));
758 //Check for the Transfer completion.
759 while (RetryCount
< MAX_RETRY_COUNT
) {
762 MmcStatus
= MmioRead32(MMCHS_STAT
);
763 } while (MmcStatus
== 0);
765 //Check if Transfer complete (TC) bit is set?
766 if (MmcStatus
& TC
) {
769 DEBUG ((EFI_D_ERROR
, "MmcStatus for TC: %x\n", MmcStatus
));
770 //Check if DEB, DCRC or DTO interrupt occured.
771 if ((MmcStatus
& DEB
) | (MmcStatus
& DCRC
) | (MmcStatus
& DTO
)) {
772 //There was an error during the data transfer.
774 //Set SRD bit to 1 and wait until it return to 0x0.
775 MmioOr32(MMCHS_SYSCTL
, SRD
);
776 while((MmioRead32(MMCHS_SYSCTL
) & SRD
) != 0x0);
778 return EFI_DEVICE_ERROR
;
784 if (RetryCount
== MAX_RETRY_COUNT
) {
785 DEBUG ((EFI_D_ERROR
, "TransferBlockData timed out.\n"));
795 IN EFI_BLOCK_IO_PROTOCOL
*This
,
799 IN OPERATION_TYPE OperationType
803 UINTN RetryCount
= 0;
806 UINTN CmdInterruptEnable
= 0;
807 UINTN CmdArgument
= 0;
809 //Check if the data lines are not in use.
810 while ((RetryCount
++ < MAX_RETRY_COUNT
) && ((MmioRead32(MMCHS_PSTATE
) & DATI_MASK
) != DATI_ALLOWED
));
811 if (RetryCount
== MAX_RETRY_COUNT
) {
815 //Populate the command information based on the operation type.
816 if (OperationType
== READ
) {
817 Cmd
= CMD17
; //Single block read
818 CmdInterruptEnable
= CMD17_INT_EN
;
819 } else if (OperationType
== WRITE
) {
820 Cmd
= CMD24
; //Single block write
821 CmdInterruptEnable
= CMD24_INT_EN
;
824 //Calculate total number of blocks its going to read.
825 NumBlocks
= (BufferSize
+ (This
->Media
->BlockSize
- 1))/This
->Media
->BlockSize
;
827 //Set command argument based on the card access mode (Byte mode or Block mode)
828 if (gCardInfo
->OCRData
.AccessMode
& BIT1
) {
829 CmdArgument
= (UINTN
)Lba
;
831 CmdArgument
= (UINTN
)Lba
* This
->Media
->BlockSize
;
836 Status
= SendCmd(Cmd
, CmdInterruptEnable
, CmdArgument
);
837 if (EFI_ERROR(Status
)) {
838 DEBUG ((EFI_D_ERROR
, "CMD fails. Status: %x\n", Status
));
842 //Transfer a block worth of data.
843 Status
= TransferBlockData(This
, Buffer
, OperationType
);
844 if (EFI_ERROR(Status
)) {
845 DEBUG ((EFI_D_ERROR
, "TransferBlockData fails. %x\n", Status
));
849 //Adjust command argument.
850 if (gCardInfo
->OCRData
.AccessMode
& BIT1
) {
851 CmdArgument
++; //Increase BlockIndex by one.
853 CmdArgument
+= This
->Media
->BlockSize
; //Increase BlockIndex by BlockSize
857 Buffer
= (UINT8
*)Buffer
+ This
->Media
->BlockSize
;
867 IN EFI_BLOCK_IO_PROTOCOL
*This
,
868 IN BOOLEAN ExtendedVerification
877 IN EFI_BLOCK_IO_PROTOCOL
*This
,
888 return EFI_INVALID_PARAMETER
;
891 if (Lba
> This
->Media
->LastBlock
)
893 return EFI_INVALID_PARAMETER
;
896 if ((BufferSize
% This
->Media
->BlockSize
) != 0)
898 return EFI_BAD_BUFFER_SIZE
;
901 //Perform Read operation.
902 Status
= SdReadWrite(This
, (UINTN
)Lba
, Buffer
, BufferSize
, READ
);
903 if (EFI_ERROR(Status
)) {
904 DEBUG ((EFI_D_ERROR
, "Read operation fails.\n"));
913 IN EFI_BLOCK_IO_PROTOCOL
*This
,
922 if (Buffer
== NULL
) {
923 return EFI_INVALID_PARAMETER
;
926 if (Lba
> This
->Media
->LastBlock
) {
927 return EFI_INVALID_PARAMETER
;
930 if ((BufferSize
% This
->Media
->BlockSize
) != 0) {
931 return EFI_BAD_BUFFER_SIZE
;
934 if (This
->Media
->ReadOnly
) {
935 return EFI_WRITE_PROTECTED
;
938 //Perform write operation.
939 Status
= SdReadWrite(This
, (UINTN
)Lba
, Buffer
, BufferSize
, WRITE
);
940 if (EFI_ERROR(Status
)) {
941 DEBUG ((EFI_D_ERROR
, "Write operation fails.\n"));
950 IN EFI_BLOCK_IO_PROTOCOL
*This
956 EFI_BLOCK_IO_PROTOCOL BlockIo
=
958 EFI_BLOCK_IO_INTERFACE_REVISION
, // Revision
959 &MMCHSMedia
, // *Media
961 MMCHSReadBlocks
, // ReadBlocks
962 MMCHSWriteBlocks
, // WriteBlocks
963 MMCHSFlushBlocks
// FlushBlocks
968 IN EFI_HANDLE ImageHandle
,
969 IN EFI_SYSTEM_TABLE
*SystemTable
974 Status
= gBS
->LocateProtocol(&gEmbeddedExternalDeviceProtocolGuid
, NULL
, (VOID
**)&gTPS65950
);
975 ASSERT_EFI_ERROR(Status
);
977 gCardInfo
= (CARD_INFO
*)AllocateZeroPool(sizeof(CARD_INFO
));
978 if (gCardInfo
== NULL
) {
979 return EFI_OUT_OF_RESOURCES
;
982 //Initialize MMC host controller.
983 Status
= InitializeMMCHS();
984 if (EFI_ERROR(Status
)) {
985 DEBUG ((EFI_D_ERROR
, "Initialize MMC host controller fails. Status: %x\n", Status
));
990 Status
= PerformCardIdenfication();
991 if (EFI_ERROR(Status
)) {
992 DEBUG ((EFI_D_ERROR
, "No MMC/SD card detected.\n"));
993 return EFI_SUCCESS
; //NOTE: Check if this is correct..
996 //Get CSD (Card specific data) for the detected card.
997 Status
= GetCardSpecificData();
998 if (EFI_ERROR(Status
)) {
1002 //Configure the card in data transfer mode.
1003 Status
= PerformCardConfiguration();
1004 if (EFI_ERROR(Status
)) {
1008 //Patch the Media structure.
1009 MMCHSMedia
.LastBlock
= (gCardInfo
->NumBlocks
- 1);
1010 MMCHSMedia
.BlockSize
= gCardInfo
->BlockSize
;
1013 Status
= gBS
->InstallMultipleProtocolInterfaces(&ImageHandle
,
1014 &gEfiBlockIoProtocolGuid
, &BlockIo
,
1015 &gEfiDevicePathProtocolGuid
, &gMmcHsDevicePath
,