]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Universal/MmcDxe/MmcIdentification.c
EmbeddedPkg: MmcDxe: wait OCR busy bit free
[mirror_edk2.git] / EmbeddedPkg / Universal / MmcDxe / MmcIdentification.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
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
9 *
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.
12 *
13 **/
14
15 #include "Mmc.h"
16
17 typedef union {
18 UINT32 Raw;
19 OCR Ocr;
20 } OCR_RESPONSE;
21
22 #define MAX_RETRY_COUNT 1000
23 #define CMD_RETRY_COUNT 20
24 #define RCA_SHIFT_OFFSET 16
25 #define EMMC_CARD_SIZE 512
26 #define EMMC_ECSD_SIZE_OFFSET 53
27
28 UINT32 mEmmcRcaCount = 0;
29
30 STATIC
31 EFI_STATUS
32 EFIAPI
33 EmmcIdentificationMode (
34 IN MMC_HOST_INSTANCE *MmcHostInstance,
35 IN OCR_RESPONSE Response
36 )
37 {
38 EFI_MMC_HOST_PROTOCOL *Host;
39 EFI_BLOCK_IO_MEDIA *Media;
40 EFI_STATUS Status;
41 UINT32 RCA;
42 UINT32 ECSD[128];
43
44 Host = MmcHostInstance->MmcHost;
45 Media = MmcHostInstance->BlockIo.Media;
46
47 // Fetch card identity register
48 Status = Host->SendCommand (Host, MMC_CMD2, 0);
49 if (EFI_ERROR (Status)) {
50 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD2, Status=%r.\n", Status));
51 return Status;
52 }
53
54 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CIDData));
55 if (EFI_ERROR (Status)) {
56 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CID retrieval error, Status=%r.\n", Status));
57 return Status;
58 }
59
60 // Assign a relative address value to the card
61 MmcHostInstance->CardInfo.RCA = ++mEmmcRcaCount; // TODO: might need a more sophisticated way of doing this
62 RCA = MmcHostInstance->CardInfo.RCA << RCA_SHIFT_OFFSET;
63 Status = Host->SendCommand (Host, MMC_CMD3, RCA);
64 if (EFI_ERROR (Status)) {
65 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): RCA set error, Status=%r.\n", Status));
66 return Status;
67 }
68
69 // Fetch card specific data
70 Status = Host->SendCommand (Host, MMC_CMD9, RCA);
71 if (EFI_ERROR (Status)) {
72 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Failed to send CMD9, Status=%r.\n", Status));
73 return Status;
74 }
75
76 Status = Host->ReceiveResponse (Host, MMC_RESPONSE_TYPE_R2, (UINT32 *)&(MmcHostInstance->CardInfo.CSDData));
77 if (EFI_ERROR (Status)) {
78 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): CSD retrieval error, Status=%r.\n", Status));
79 return Status;
80 }
81
82 // Select the card
83 Status = Host->SendCommand (Host, MMC_CMD7, RCA);
84 if (EFI_ERROR (Status)) {
85 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): Card selection error, Status=%r.\n", Status));
86 }
87
88 // Fetch ECSD
89 Status = Host->SendCommand (Host, MMC_CMD8, RCA);
90 if (EFI_ERROR (Status)) {
91 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD fetch error, Status=%r.\n", Status));
92 }
93
94 Status = Host->ReadBlockData (Host, 0, 512, ECSD);
95 if (EFI_ERROR (Status)) {
96 DEBUG ((EFI_D_ERROR, "EmmcIdentificationMode(): ECSD read error, Status=%r.\n", Status));
97 return Status;
98 }
99
100 // Set up media
101 Media->BlockSize = EMMC_CARD_SIZE; // 512-byte support is mandatory for eMMC cards
102 Media->MediaId = MmcHostInstance->CardInfo.CIDData.PSN;
103 Media->ReadOnly = MmcHostInstance->CardInfo.CSDData.PERM_WRITE_PROTECT;
104 Media->LogicalBlocksPerPhysicalBlock = 1;
105 Media->IoAlign = 4;
106 // Compute last block using bits [215:212] of the ECSD
107 Media->LastBlock = ECSD[EMMC_ECSD_SIZE_OFFSET] - 1; // eMMC isn't supposed to report this for
108 // Cards <2GB in size, but the model does.
109
110 // Setup card type
111 MmcHostInstance->CardInfo.CardType = EMMC_CARD;
112 return EFI_SUCCESS;
113 }
114
115 STATIC
116 EFI_STATUS
117 InitializeSdMmcDevice (
118 IN MMC_HOST_INSTANCE *MmcHostInstance
119 )
120 {
121 UINT32 CmdArg;
122 UINT32 Response[4];
123 UINTN BlockSize;
124 UINTN CardSize;
125 UINTN NumBlocks;
126 EFI_STATUS Status;
127 EFI_MMC_HOST_PROTOCOL *MmcHost;
128
129 MmcHost = MmcHostInstance->MmcHost;
130
131 // Send a command to get Card specific data
132 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
133 Status = MmcHost->SendCommand (MmcHost, MMC_CMD9, CmdArg);
134 if (EFI_ERROR (Status)) {
135 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD9): Error, Status=%r\n", Status));
136 return Status;
137 }
138
139 // Read Response
140 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CSD, Response);
141 if (EFI_ERROR (Status)) {
142 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(): Failed to receive CSD, Status=%r\n", Status));
143 return Status;
144 }
145 PrintCSD (Response);
146
147 if (MmcHostInstance->CardInfo.CardType == SD_CARD_2_HIGH) {
148 CardSize = HC_MMC_CSD_GET_DEVICESIZE (Response);
149 NumBlocks = ((CardSize + 1) * 1024);
150 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
151 } else {
152 CardSize = MMC_CSD_GET_DEVICESIZE (Response);
153 NumBlocks = (CardSize + 1) * (1 << (MMC_CSD_GET_DEVICESIZEMULT (Response) + 2));
154 BlockSize = 1 << MMC_CSD_GET_READBLLEN (Response);
155 }
156
157 // For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
158 if (BlockSize > 512) {
159 NumBlocks = MultU64x32 (NumBlocks, BlockSize / 512);
160 BlockSize = 512;
161 }
162
163 MmcHostInstance->BlockIo.Media->LastBlock = (NumBlocks - 1);
164 MmcHostInstance->BlockIo.Media->BlockSize = BlockSize;
165 MmcHostInstance->BlockIo.Media->ReadOnly = MmcHost->IsReadOnly (MmcHost);
166 MmcHostInstance->BlockIo.Media->MediaPresent = TRUE;
167 MmcHostInstance->BlockIo.Media->MediaId++;
168
169 CmdArg = MmcHostInstance->CardInfo.RCA << 16;
170 Status = MmcHost->SendCommand (MmcHost, MMC_CMD7, CmdArg);
171 if (EFI_ERROR (Status)) {
172 DEBUG((EFI_D_ERROR, "InitializeSdMmcDevice(MMC_CMD7): Error and Status = %r\n", Status));
173 return Status;
174 }
175
176 return EFI_SUCCESS;
177 }
178
179 STATIC
180 EFI_STATUS
181 EFIAPI
182 MmcIdentificationMode (
183 IN MMC_HOST_INSTANCE *MmcHostInstance
184 )
185 {
186 EFI_STATUS Status;
187 UINT32 Response[4];
188 UINTN Timeout;
189 UINTN CmdArg;
190 BOOLEAN IsHCS;
191 EFI_MMC_HOST_PROTOCOL *MmcHost;
192 OCR_RESPONSE OcrResponse;
193
194 MmcHost = MmcHostInstance->MmcHost;
195 CmdArg = 0;
196 IsHCS = FALSE;
197
198 if (MmcHost == NULL) {
199 return EFI_INVALID_PARAMETER;
200 }
201
202 // We can get into this function if we restart the identification mode
203 if (MmcHostInstance->State == MmcHwInitializationState) {
204 // Initialize the MMC Host HW
205 Status = MmcNotifyState (MmcHostInstance, MmcHwInitializationState);
206 if (EFI_ERROR (Status)) {
207 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcHwInitializationState, Status=%r.\n", Status));
208 return Status;
209 }
210 }
211
212 Status = MmcHost->SendCommand (MmcHost, MMC_CMD0, 0);
213 if (EFI_ERROR (Status)) {
214 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD0): Error, Status=%r.\n", Status));
215 return Status;
216 }
217 Status = MmcNotifyState (MmcHostInstance, MmcIdleState);
218 if (EFI_ERROR (Status)) {
219 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdleState, Status=%r.\n", Status));
220 return Status;
221 }
222
223 // Send CMD1 to get OCR (MMC)
224 // This command only valid for MMC and eMMC
225 Timeout = MAX_RETRY_COUNT;
226 do {
227 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, EMMC_CMD1_CAPACITY_GREATER_THAN_2GB);
228 if (EFI_ERROR (Status))
229 break;
230 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, (UINT32 *)&OcrResponse);
231 if (EFI_ERROR (Status)) {
232 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
233 return Status;
234 }
235 Timeout--;
236 } while (!OcrResponse.Ocr.PowerUp && (Timeout > 0));
237 if (Status == EFI_SUCCESS) {
238 if (!OcrResponse.Ocr.PowerUp) {
239 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD1): Card initialisation failure, Status=%r.\n", Status));
240 return EFI_DEVICE_ERROR;
241 }
242 OcrResponse.Ocr.PowerUp = 0;
243 if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB) {
244 MmcHostInstance->CardInfo.OCRData.AccessMode = BIT1;
245 }
246 else {
247 MmcHostInstance->CardInfo.OCRData.AccessMode = 0x0;
248 }
249 // Check whether MMC or eMMC
250 if (OcrResponse.Raw == EMMC_CMD1_CAPACITY_GREATER_THAN_2GB ||
251 OcrResponse.Raw == EMMC_CMD1_CAPACITY_LESS_THAN_2GB) {
252 return EmmcIdentificationMode (MmcHostInstance, OcrResponse);
253 }
254 }
255
256 // Are we using SDIO ?
257 Status = MmcHost->SendCommand (MmcHost, MMC_CMD5, 0);
258 if (Status == EFI_SUCCESS) {
259 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD5): Error - SDIO not supported, Status=%r.\n", Status));
260 return EFI_UNSUPPORTED;
261 }
262
263 // Check which kind of card we are using. Ver2.00 or later SD Memory Card (PL180 is SD v1.1)
264 CmdArg = (0x0UL << 12 | BIT8 | 0xCEUL << 0);
265 Status = MmcHost->SendCommand (MmcHost, MMC_CMD8, CmdArg);
266 if (Status == EFI_SUCCESS) {
267 DEBUG ((EFI_D_ERROR, "Card is SD2.0 => Supports high capacity\n"));
268 IsHCS = TRUE;
269 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_R7, Response);
270 if (EFI_ERROR (Status)) {
271 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive response to CMD8, Status=%r.\n", Status));
272 return Status;
273 }
274 PrintResponseR1 (Response[0]);
275 // Check if it is valid response
276 if (Response[0] != CmdArg) {
277 DEBUG ((EFI_D_ERROR, "The Card is not usable\n"));
278 return EFI_UNSUPPORTED;
279 }
280 } else {
281 DEBUG ((EFI_D_ERROR, "Not a SD2.0 Card\n"));
282 }
283
284 // We need to wait for the MMC or SD card is ready => (gCardInfo.OCRData.PowerUp == 1)
285 Timeout = MAX_RETRY_COUNT;
286 while (Timeout > 0) {
287 // SD Card or MMC Card ? CMD55 indicates to the card that the next command is an application specific command
288 Status = MmcHost->SendCommand (MmcHost, MMC_CMD55, 0);
289 if (Status == EFI_SUCCESS) {
290 DEBUG ((EFI_D_INFO, "Card should be SD\n"));
291 if (IsHCS) {
292 MmcHostInstance->CardInfo.CardType = SD_CARD_2;
293 } else {
294 MmcHostInstance->CardInfo.CardType = SD_CARD;
295 }
296
297 // Note: The first time CmdArg will be zero
298 CmdArg = ((UINTN *) &(MmcHostInstance->CardInfo.OCRData))[0];
299 if (IsHCS) {
300 CmdArg |= BIT30;
301 }
302 Status = MmcHost->SendCommand (MmcHost, MMC_ACMD41, CmdArg);
303 if (!EFI_ERROR (Status)) {
304 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
305 if (EFI_ERROR (Status)) {
306 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
307 return Status;
308 }
309 ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
310 }
311 } else {
312 DEBUG ((EFI_D_INFO, "Card should be MMC\n"));
313 MmcHostInstance->CardInfo.CardType = MMC_CARD;
314
315 Status = MmcHost->SendCommand (MmcHost, MMC_CMD1, 0x800000);
316 if (!EFI_ERROR (Status)) {
317 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_OCR, Response);
318 if (EFI_ERROR (Status)) {
319 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive OCR, Status=%r.\n", Status));
320 return Status;
321 }
322 ((UINT32 *) &(MmcHostInstance->CardInfo.OCRData))[0] = Response[0];
323 }
324 }
325
326 if (!EFI_ERROR (Status)) {
327 if (!MmcHostInstance->CardInfo.OCRData.PowerUp) {
328 gBS->Stall (1);
329 Timeout--;
330 } else {
331 if ((MmcHostInstance->CardInfo.CardType == SD_CARD_2) && (MmcHostInstance->CardInfo.OCRData.AccessMode & BIT1)) {
332 MmcHostInstance->CardInfo.CardType = SD_CARD_2_HIGH;
333 DEBUG ((EFI_D_ERROR, "High capacity card.\n"));
334 }
335 break; // The MMC/SD card is ready. Continue the Identification Mode
336 }
337 } else {
338 gBS->Stall (1);
339 Timeout--;
340 }
341 }
342
343 if (Timeout == 0) {
344 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(): No Card\n"));
345 return EFI_NO_MEDIA;
346 } else {
347 PrintOCR (Response[0]);
348 }
349
350 Status = MmcNotifyState (MmcHostInstance, MmcReadyState);
351 if (EFI_ERROR (Status)) {
352 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcReadyState\n"));
353 return Status;
354 }
355
356 Status = MmcHost->SendCommand (MmcHost, MMC_CMD2, 0);
357 if (EFI_ERROR (Status)) {
358 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD2): Error\n"));
359 return Status;
360 }
361 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_CID, Response);
362 if (EFI_ERROR (Status)) {
363 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive CID, Status=%r.\n", Status));
364 return Status;
365 }
366
367 PrintCID (Response);
368
369 Status = MmcHost->NotifyState (MmcHost, MmcIdentificationState);
370 if (EFI_ERROR (Status)) {
371 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcIdentificationState\n"));
372 return Status;
373 }
374
375 //
376 // Note, SD specifications say that "if the command execution causes a state change, it
377 // will be visible to the host in the response to the next command"
378 // The status returned for this CMD3 will be 2 - identification
379 //
380 CmdArg = 1;
381 Status = MmcHost->SendCommand (MmcHost, MMC_CMD3, CmdArg);
382 if (EFI_ERROR (Status)) {
383 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode(MMC_CMD3): Error\n"));
384 return Status;
385 }
386
387 Status = MmcHost->ReceiveResponse (MmcHost, MMC_RESPONSE_TYPE_RCA, Response);
388 if (EFI_ERROR (Status)) {
389 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Failed to receive RCA, Status=%r.\n", Status));
390 return Status;
391 }
392 PrintRCA (Response[0]);
393
394 // For MMC card, RCA is assigned by CMD3 while CMD3 dumps the RCA for SD card
395 if (MmcHostInstance->CardInfo.CardType != MMC_CARD) {
396 MmcHostInstance->CardInfo.RCA = Response[0] >> 16;
397 } else {
398 MmcHostInstance->CardInfo.RCA = CmdArg;
399 }
400 Status = MmcNotifyState (MmcHostInstance, MmcStandByState);
401 if (EFI_ERROR (Status)) {
402 DEBUG ((EFI_D_ERROR, "MmcIdentificationMode() : Error MmcStandByState\n"));
403 return Status;
404 }
405
406 return EFI_SUCCESS;
407 }
408
409 EFI_STATUS
410 InitializeMmcDevice (
411 IN MMC_HOST_INSTANCE *MmcHostInstance
412 )
413 {
414 EFI_STATUS Status;
415 EFI_MMC_HOST_PROTOCOL *MmcHost;
416 UINTN BlockCount;
417
418 BlockCount = 1;
419 MmcHost = MmcHostInstance->MmcHost;
420
421 Status = MmcIdentificationMode (MmcHostInstance);
422 if (EFI_ERROR (Status)) {
423 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error in Identification Mode, Status=%r\n", Status));
424 return Status;
425 }
426
427 Status = MmcNotifyState (MmcHostInstance, MmcTransferState);
428 if (EFI_ERROR (Status)) {
429 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(): Error MmcTransferState, Status=%r\n", Status));
430 return Status;
431 }
432
433 if (MmcHostInstance->CardInfo.CardType != EMMC_CARD) {
434 Status = InitializeSdMmcDevice (MmcHostInstance);
435 if (EFI_ERROR (Status)) {
436 return Status;
437 }
438 }
439
440 // Set Block Length
441 Status = MmcHost->SendCommand (MmcHost, MMC_CMD16, MmcHostInstance->BlockIo.Media->BlockSize);
442 if (EFI_ERROR (Status)) {
443 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD16): Error MmcHostInstance->BlockIo.Media->BlockSize: %d and Error = %r\n",
444 MmcHostInstance->BlockIo.Media->BlockSize, Status));
445 return Status;
446 }
447
448 // Block Count (not used). Could return an error for SD card
449 if (MmcHostInstance->CardInfo.CardType == MMC_CARD) {
450 Status = MmcHost->SendCommand (MmcHost, MMC_CMD23, BlockCount);
451 if (EFI_ERROR (Status)) {
452 DEBUG((EFI_D_ERROR, "InitializeMmcDevice(MMC_CMD23): Error, Status=%r\n", Status));
453 return Status;
454 }
455 }
456
457 return EFI_SUCCESS;
458 }