3 * Copyright (c) 2011-2013, ARM Limited. All rights reserved.
5 * 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.
15 #include <Library/BaseMemoryLib.h>
16 #include <Library/TimerLib.h>
20 #define MAX_RETRY_COUNT 1000
21 #define CMD_RETRY_COUNT 20
25 IN MMC_HOST_INSTANCE
*MmcHostInstance
,
29 MmcHostInstance
->State
= State
;
30 return MmcHostInstance
->MmcHost
->NotifyState (MmcHostInstance
->MmcHost
, State
);
36 IN MMC_HOST_INSTANCE
*MmcHostInstance
42 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
45 MmcHost
= MmcHostInstance
->MmcHost
;
48 if (MmcHost
== NULL
) {
49 return EFI_INVALID_PARAMETER
;
51 if (MmcHostInstance
->State
!= MmcHwInitializationState
) {
52 //Get the Status of the card.
53 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
54 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
55 if (EFI_ERROR (Status
)) {
56 DEBUG ((EFI_D_ERROR
, "MmcGetCardStatus(MMC_CMD13): Error and Status = %r\n", Status
));
61 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
62 PrintResponseR1 (Response
[0]);
70 MmcIdentificationMode (
71 IN MMC_HOST_INSTANCE
*MmcHostInstance
79 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
81 MmcHost
= MmcHostInstance
->MmcHost
;
85 if (MmcHost
== NULL
) {
86 return EFI_INVALID_PARAMETER
;
89 // We can get into this function if we restart the identification mode
90 if (MmcHostInstance
->State
== MmcHwInitializationState
) {
91 // Initialize the MMC Host HW
92 Status
= MmcNotifyState (MmcHostInstance
, MmcHwInitializationState
);
93 if (EFI_ERROR (Status
)) {
94 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcHwInitializationState\n"));
99 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD0
, 0);
100 if (EFI_ERROR (Status
)) {
101 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD0): Error\n"));
105 Status
= MmcNotifyState (MmcHostInstance
, MmcIdleState
);
106 if (EFI_ERROR (Status
)) {
107 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcIdleState\n"));
111 // Are we using SDIO ?
112 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD5
, 0);
113 if (Status
== EFI_SUCCESS
) {
114 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported.\n"));
115 return EFI_UNSUPPORTED
;
118 // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
119 CmdArg
= (0x0UL
<< 12 | BIT8
| 0xCEUL
<< 0);
120 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD8
, CmdArg
);
121 if (Status
== EFI_SUCCESS
) {
122 DEBUG ((EFI_D_ERROR
, "Card is SD2.0 => Supports high capacity\n"));
124 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R7
, Response
);
125 PrintResponseR1 (Response
[0]);
126 //check if it is valid response
127 if (Response
[0] != CmdArg
) {
128 DEBUG ((EFI_D_ERROR
, "The Card is not usable\n"));
129 return EFI_UNSUPPORTED
;
132 DEBUG ((EFI_D_ERROR
, "Not a SD2.0 Card\n"));
135 // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
136 Timeout
= MAX_RETRY_COUNT
;
137 while (Timeout
> 0) {
138 // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
139 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD55
, 0);
140 if (Status
== EFI_SUCCESS
) {
141 DEBUG ((EFI_D_INFO
, "Card should be SD\n"));
143 MmcHostInstance
->CardInfo
.CardType
= SD_CARD_2
;
145 MmcHostInstance
->CardInfo
.CardType
= SD_CARD
;
148 // Note: The first time CmdArg will be zero
149 CmdArg
= ((UINTN
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0];
153 Status
= MmcHost
->SendCommand (MmcHost
, MMC_ACMD41
, CmdArg
);
154 if (!EFI_ERROR (Status
)) {
155 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_OCR
, Response
);
156 ((UINT32
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0] = Response
[0];
159 DEBUG ((EFI_D_INFO
, "Card should be MMC\n"));
160 MmcHostInstance
->CardInfo
.CardType
= MMC_CARD
;
162 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD1
, 0x800000);
163 if (!EFI_ERROR (Status
)) {
164 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_OCR
, Response
);
165 ((UINT32
*) &(MmcHostInstance
->CardInfo
.OCRData
))[0] = Response
[0];
169 if (!EFI_ERROR (Status
)) {
170 if (!MmcHostInstance
->CardInfo
.OCRData
.PowerUp
) {
171 MicroSecondDelay (1);
174 if ((MmcHostInstance
->CardInfo
.CardType
== SD_CARD_2
) && (MmcHostInstance
->CardInfo
.OCRData
.AccessMode
& BIT1
)) {
175 MmcHostInstance
->CardInfo
.CardType
= SD_CARD_2_HIGH
;
176 DEBUG ((EFI_D_ERROR
, "High capacity card.\n"));
178 break; // The MMC/SD card is ready. Continue the Identification Mode
181 MicroSecondDelay (1);
187 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(): No Card\n"));
190 PrintOCR (Response
[0]);
193 Status
= MmcNotifyState (MmcHostInstance
, MmcReadyState
);
194 if (EFI_ERROR (Status
)) {
195 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcReadyState\n"));
199 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD2
, 0);
200 if (EFI_ERROR (Status
)) {
201 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD2): Error\n"));
204 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_CID
, Response
);
207 Status
= MmcNotifyState (MmcHostInstance
, MmcIdentificationState
);
208 if (EFI_ERROR (Status
)) {
209 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
214 // Note, SD specifications say that "if the command execution causes a state change, it
215 // will be visible to the host in the response to the next command"
216 // The status returned for this CMD3 will be 2 - identification
219 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD3
, CmdArg
);
220 if (EFI_ERROR (Status
)) {
221 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode(MMC_CMD3): Error\n"));
225 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_RCA
, Response
);
226 PrintRCA (Response
[0]);
228 // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
229 if (MmcHostInstance
->CardInfo
.CardType
!= MMC_CARD
) {
230 MmcHostInstance
->CardInfo
.RCA
= Response
[0] >> 16;
232 MmcHostInstance
->CardInfo
.RCA
= CmdArg
;
235 Status
= MmcNotifyState (MmcHostInstance
, MmcStandByState
);
236 if (EFI_ERROR (Status
)) {
237 DEBUG ((EFI_D_ERROR
, "MmcIdentificationMode() : Error MmcStandByState\n"));
244 EFI_STATUS
InitializeMmcDevice (
245 IN MMC_HOST_INSTANCE
*MmcHostInstance
250 UINTN CardSize
, NumBlocks
, BlockSize
, CmdArg
;
251 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
255 MmcHost
= MmcHostInstance
->MmcHost
;
257 MmcIdentificationMode (MmcHostInstance
);
259 //Send a command to get Card specific data
260 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
261 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD9
, CmdArg
);
262 if (EFI_ERROR (Status
)) {
263 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD9): Error, Status=%r\n", Status
));
267 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_CSD
, Response
);
270 if (MmcHostInstance
->CardInfo
.CardType
== SD_CARD_2_HIGH
) {
271 CardSize
= HC_MMC_CSD_GET_DEVICESIZE (Response
);
272 NumBlocks
= ((CardSize
+ 1) * 1024);
273 BlockSize
= 1 << MMC_CSD_GET_READBLLEN (Response
);
275 CardSize
= MMC_CSD_GET_DEVICESIZE (Response
);
276 NumBlocks
= (CardSize
+ 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response
) + 2));
277 BlockSize
= 1 << MMC_CSD_GET_READBLLEN (Response
);
280 //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
281 if (BlockSize
> 512) {
282 NumBlocks
= MultU64x32 (NumBlocks
, BlockSize
/512);
286 MmcHostInstance
->BlockIo
.Media
->LastBlock
= (NumBlocks
- 1);
287 MmcHostInstance
->BlockIo
.Media
->BlockSize
= BlockSize
;
288 MmcHostInstance
->BlockIo
.Media
->ReadOnly
= MmcHost
->IsReadOnly (MmcHost
);
289 MmcHostInstance
->BlockIo
.Media
->MediaPresent
= TRUE
;
290 MmcHostInstance
->BlockIo
.Media
->MediaId
++;
292 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
293 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD7
, CmdArg
);
294 if (EFI_ERROR (Status
)) {
295 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD7): Error and Status = %r\n", Status
));
299 Status
= MmcNotifyState (MmcHostInstance
, MmcTransferState
);
300 if (EFI_ERROR (Status
)) {
301 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(): Error MmcTransferState\n"));
306 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD16
, MmcHostInstance
->BlockIo
.Media
->BlockSize
);
307 if (EFI_ERROR (Status
)) {
308 DEBUG((EFI_D_ERROR
, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
309 MmcHostInstance
->BlockIo
.Media
->BlockSize
, Status
));
313 // Block Count (not used). Could return an error for SD card
314 if (MmcHostInstance
->CardInfo
.CardType
== MMC_CARD
) {
315 MmcHost
->SendCommand (MmcHost
, MMC_CMD23
, BlockCount
);
324 IN EFI_BLOCK_IO_PROTOCOL
*This
,
325 IN BOOLEAN ExtendedVerification
328 MMC_HOST_INSTANCE
*MmcHostInstance
;
330 MmcHostInstance
= MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS (This
);
332 if (MmcHostInstance
->MmcHost
== NULL
) {
337 // If a card is not present then clear all media settings
338 if (!MmcHostInstance
->MmcHost
->IsCardPresent (MmcHostInstance
->MmcHost
)) {
339 MmcHostInstance
->BlockIo
.Media
->MediaPresent
= FALSE
;
340 MmcHostInstance
->BlockIo
.Media
->LastBlock
= 0;
341 MmcHostInstance
->BlockIo
.Media
->BlockSize
= 512; // Should be zero but there is a bug in DiskIo
342 MmcHostInstance
->BlockIo
.Media
->ReadOnly
= FALSE
;
344 // Indicate that the driver requires initialization
345 MmcHostInstance
->State
= MmcHwInitializationState
;
350 // Implement me. Either send a CMD0 (could not work for some MMC host) or just turn off/turn
351 // on power and restart Identification mode
357 EFI_MMC_HOST_PROTOCOL
*MmcHost
360 if (!MmcHost
->IsCardPresent (MmcHost
)) {
368 MmcStopTransmission (
369 EFI_MMC_HOST_PROTOCOL
*MmcHost
374 // Command 12 - Stop transmission (ends read or write)
375 // Normally only needed for streaming transfers or after error.
376 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD12
, 0);
377 if (!EFI_ERROR (Status
)) {
378 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1b
, Response
);
383 #define MMCI0_BLOCKLEN 512
384 #define MMCI0_TIMEOUT 10000
388 IN EFI_BLOCK_IO_PROTOCOL
*This
,
401 MMC_HOST_INSTANCE
*MmcHostInstance
;
402 EFI_MMC_HOST_PROTOCOL
*MmcHost
;
403 UINTN BytesRemainingToBeTransfered
;
407 MmcHostInstance
= MMC_HOST_INSTANCE_FROM_BLOCK_IO_THIS (This
);
408 ASSERT (MmcHostInstance
!= NULL
);
409 MmcHost
= MmcHostInstance
->MmcHost
;
412 if (This
->Media
->MediaId
!= MediaId
) {
413 return EFI_MEDIA_CHANGED
;
416 if ((MmcHost
== NULL
) || (Buffer
== NULL
)) {
417 return EFI_INVALID_PARAMETER
;
420 // Check if a Card is Present
421 if (!MmcHostInstance
->BlockIo
.Media
->MediaPresent
) {
425 // All blocks must be within the device
426 if ((Lba
+ (BufferSize
/ This
->Media
->BlockSize
)) > (This
->Media
->LastBlock
+ 1)) {
427 return EFI_INVALID_PARAMETER
;
430 if ((Transfer
== MMC_IOBLOCKS_WRITE
) && (This
->Media
->ReadOnly
== TRUE
)) {
431 return EFI_WRITE_PROTECTED
;
434 // Reading 0 Byte is valid
435 if (BufferSize
== 0) {
439 // The buffer size must be an exact multiple of the block size
440 if ((BufferSize
% This
->Media
->BlockSize
) != 0) {
441 return EFI_BAD_BUFFER_SIZE
;
444 // Check the alignment
445 if ((This
->Media
->IoAlign
> 2) && (((UINTN
)Buffer
& (This
->Media
->IoAlign
- 1)) != 0)) {
446 return EFI_INVALID_PARAMETER
;
449 BytesRemainingToBeTransfered
= BufferSize
;
450 while (BytesRemainingToBeTransfered
> 0) {
452 // Check if the Card is in Ready status
453 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
456 while( (!(Response
[0] & MMC_R0_READY_FOR_DATA
))
457 && (MMC_R0_CURRENTSTATE (Response
) != MMC_R0_STATE_TRAN
)
459 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
460 if (!EFI_ERROR (Status
)) {
461 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
466 DEBUG ((EFI_D_ERROR
, "The Card is busy\n"));
467 return EFI_NOT_READY
;
470 //Set command argument based on the card access mode (Byte mode or Block mode)
471 if (MmcHostInstance
->CardInfo
.OCRData
.AccessMode
& BIT1
) {
474 CmdArg
= Lba
* This
->Media
->BlockSize
;
477 if (Transfer
== MMC_IOBLOCKS_READ
) {
478 // Read a single block
481 // Write a single block
484 Status
= MmcHost
->SendCommand (MmcHost
, Cmd
, CmdArg
);
485 if (EFI_ERROR (Status
)) {
486 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks(MMC_CMD%d): Error %r\n", Cmd
, Status
));
490 if (Transfer
== MMC_IOBLOCKS_READ
) {
491 // Read one block of Data
492 Status
= MmcHost
->ReadBlockData (MmcHost
, Lba
, This
->Media
->BlockSize
, Buffer
);
493 if (EFI_ERROR (Status
)) {
494 DEBUG ((EFI_D_BLKIO
, "MmcIoBlocks(): Error Read Block Data and Status = %r\n", Status
));
495 MmcStopTransmission (MmcHost
);
498 Status
= MmcNotifyState (MmcHostInstance
, MmcProgrammingState
);
499 if (EFI_ERROR (Status
)) {
500 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks() : Error MmcProgrammingState\n"));
504 // Write one block of Data
505 Status
= MmcHost
->WriteBlockData (MmcHost
, Lba
, This
->Media
->BlockSize
, Buffer
);
506 if (EFI_ERROR (Status
)) {
507 DEBUG ((EFI_D_BLKIO
, "MmcIoBlocks(): Error Write Block Data and Status = %r\n", Status
));
508 MmcStopTransmission (MmcHost
);
513 // Command 13 - Read status and wait for programming to complete (return to tran)
514 Timeout
= MMCI0_TIMEOUT
;
515 CmdArg
= MmcHostInstance
->CardInfo
.RCA
<< 16;
517 while( (!(Response
[0] & MMC_R0_READY_FOR_DATA
))
518 && (MMC_R0_CURRENTSTATE (Response
) != MMC_R0_STATE_TRAN
)
520 Status
= MmcHost
->SendCommand (MmcHost
, MMC_CMD13
, CmdArg
);
521 if (!EFI_ERROR (Status
)) {
522 MmcHost
->ReceiveResponse (MmcHost
, MMC_RESPONSE_TYPE_R1
, Response
);
523 if ((Response
[0] & MMC_R0_READY_FOR_DATA
)) {
524 break; // Prevents delay once finished
527 NanoSecondDelay (100);
530 Status
= MmcNotifyState (MmcHostInstance
, MmcTransferState
);
531 if (EFI_ERROR (Status
)) {
532 DEBUG ((EFI_D_ERROR
, "MmcIoBlocks() : Error MmcTransferState\n"));
536 BytesRemainingToBeTransfered
-= This
->Media
->BlockSize
;
538 Buffer
= (UINT8
*)Buffer
+ This
->Media
->BlockSize
;
547 IN EFI_BLOCK_IO_PROTOCOL
*This
,
554 return MmcIoBlocks (This
, MMC_IOBLOCKS_READ
, MediaId
, Lba
, BufferSize
, Buffer
);
560 IN EFI_BLOCK_IO_PROTOCOL
*This
,
567 return MmcIoBlocks (This
, MMC_IOBLOCKS_WRITE
, MediaId
, Lba
, BufferSize
, Buffer
);
573 IN EFI_BLOCK_IO_PROTOCOL
*This