]> git.proxmox.com Git - mirror_edk2.git/blob - Omap35xxPkg/MMCHSDxe/MMCHS.c
61bf215f7ea4cbe685cfebab8ea623d7042bcac6
[mirror_edk2.git] / Omap35xxPkg / MMCHSDxe / MMCHS.c
1 /** @file
2 MMC/SD Card driver for OMAP 35xx (SDIO not supported)
3
4 This driver always produces a BlockIo protocol but it starts off with no Media
5 present. A TimerCallBack detects when media is inserted or removed and after
6 a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
7 media to be detected (or removed) and the BlockIo Media structure will get
8 updated. No MMC/SD Card harward registers are updated until the first BlockIo
9 ReadBlocks/WriteBlocks after media has been insterted (booting with a card
10 plugged in counts as an insertion event).
11
12 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
13
14 This program and the accompanying materials
15 are licensed and made available under the terms and conditions of the BSD License
16 which accompanies this distribution. The full text of the license may be found at
17 http://opensource.org/licenses/bsd-license.php
18
19 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
20 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21
22 **/
23
24 #include <Uefi.h>
25
26 #include "MMCHS.h"
27
28 EFI_BLOCK_IO_MEDIA gMMCHSMedia = {
29 SIGNATURE_32('s','d','i','o'), // MediaId
30 TRUE, // RemovableMedia
31 FALSE, // MediaPresent
32 FALSE, // LogicalPartition
33 FALSE, // ReadOnly
34 FALSE, // WriteCaching
35 512, // BlockSize
36 4, // IoAlign
37 0, // Pad
38 0 // LastBlock
39 };
40
41 typedef struct {
42 VENDOR_DEVICE_PATH Mmc;
43 EFI_DEVICE_PATH End;
44 } MMCHS_DEVICE_PATH;
45
46 MMCHS_DEVICE_PATH gMmcHsDevicePath = {
47 {
48 HARDWARE_DEVICE_PATH,
49 HW_VENDOR_DP,
50 (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
51 (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
52 0xb615f1f5, 0x5088, 0x43cd, 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00
53 },
54 {
55 END_DEVICE_PATH_TYPE,
56 END_ENTIRE_DEVICE_PATH_SUBTYPE,
57 sizeof (EFI_DEVICE_PATH_PROTOCOL),
58 0
59 }
60 };
61
62 CARD_INFO gCardInfo;
63 EMBEDDED_EXTERNAL_DEVICE *gTPS65950;
64 EFI_EVENT gTimerEvent;
65 BOOLEAN gMediaChange = FALSE;
66
67 //
68 // Internal Functions
69 //
70
71
72 VOID
73 ParseCardCIDData (
74 UINT32 Response0,
75 UINT32 Response1,
76 UINT32 Response2,
77 UINT32 Response3
78 )
79 {
80 gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
81 gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
82 gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
83 gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
84 gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
85 gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
86 gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
87 gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
88 gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
89 gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
90 }
91
92
93 VOID
94 UpdateMMCHSClkFrequency (
95 UINTN NewCLKD
96 )
97 {
98 //Set Clock enable to 0x0 to not provide the clock to the card
99 MmioAnd32 (MMCHS_SYSCTL, ~CEN);
100
101 //Set new clock frequency.
102 MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
103
104 //Poll till Internal Clock Stable
105 while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
106
107 //Set Clock enable to 0x1 to provide the clock to the card
108 MmioOr32 (MMCHS_SYSCTL, CEN);
109 }
110
111
112 EFI_STATUS
113 SendCmd (
114 UINTN Cmd,
115 UINTN CmdInterruptEnableVal,
116 UINTN CmdArgument
117 )
118 {
119 UINTN MmcStatus;
120 UINTN RetryCount = 0;
121
122 //Check if command line is in use or not. Poll till command line is available.
123 while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
124
125 //Provide the block size.
126 MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
127
128 //Setting Data timeout counter value to max value.
129 MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
130
131 //Clear Status register.
132 MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
133
134 //Set command argument register
135 MmioWrite32 (MMCHS_ARG, CmdArgument);
136
137 //Enable interrupt enable events to occur
138 MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
139
140 //Send a command
141 MmioWrite32 (MMCHS_CMD, Cmd);
142
143 //Check for the command status.
144 while (RetryCount < MAX_RETRY_COUNT) {
145 do {
146 MmcStatus = MmioRead32 (MMCHS_STAT);
147 } while (MmcStatus == 0);
148
149 //Read status of command response
150 if ((MmcStatus & ERRI) != 0) {
151
152 //Perform soft-reset for mmci_cmd line.
153 MmioOr32 (MMCHS_SYSCTL, SRC);
154 while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
155
156 DEBUG ((EFI_D_INFO, "MmcStatus: %x\n", MmcStatus));
157 return EFI_DEVICE_ERROR;
158 }
159
160 //Check if command is completed.
161 if ((MmcStatus & CC) == CC) {
162 MmioWrite32 (MMCHS_STAT, CC);
163 break;
164 }
165
166 RetryCount++;
167 }
168
169 if (RetryCount == MAX_RETRY_COUNT) {
170 return EFI_TIMEOUT;
171 }
172
173 return EFI_SUCCESS;
174 }
175
176
177 VOID
178 GetBlockInformation (
179 UINTN *BlockSize,
180 UINTN *NumBlocks
181 )
182 {
183 CSD_SDV2 *CsdSDV2Data;
184 UINTN CardSize;
185
186 if (gCardInfo.CardType == SD_CARD_2_HIGH) {
187 CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
188
189 //Populate BlockSize.
190 *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
191
192 //Calculate Total number of blocks.
193 CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
194 *NumBlocks = ((CardSize + 1) * 1024);
195 } else {
196 //Populate BlockSize.
197 *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
198
199 //Calculate Total number of blocks.
200 CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
201 *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
202 }
203
204 //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
205 if (*BlockSize > 512) {
206 *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
207 *BlockSize = 512;
208 }
209
210 DEBUG ((EFI_D_INFO, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
211 }
212
213
214 VOID
215 CalculateCardCLKD (
216 UINTN *ClockFrequencySelect
217 )
218 {
219 UINT8 MaxDataTransferRate;
220 UINTN TransferRateValue = 0;
221 UINTN TimeValue = 0 ;
222 UINTN Frequency = 0;
223
224 MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
225
226 //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
227 switch (MaxDataTransferRate & 0x7) {
228 case 0:
229 TransferRateValue = 100 * 1000;
230 break;
231
232 case 1:
233 TransferRateValue = 1 * 1000 * 1000;
234 break;
235
236 case 2:
237 TransferRateValue = 10 * 1000 * 1000;
238 break;
239
240 case 3:
241 TransferRateValue = 100 * 1000 * 1000;
242 break;
243
244 default:
245 DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
246 ASSERT(FALSE);
247 }
248
249 //Calculate Time value (Bits 6:3 of TRAN_SPEED)
250 switch ((MaxDataTransferRate >> 3) & 0xF) {
251 case 1:
252 TimeValue = 10;
253 break;
254
255 case 2:
256 TimeValue = 12;
257 break;
258
259 case 3:
260 TimeValue = 13;
261 break;
262
263 case 4:
264 TimeValue = 15;
265 break;
266
267 case 5:
268 TimeValue = 20;
269 break;
270
271 case 6:
272 TimeValue = 25;
273 break;
274
275 case 7:
276 TimeValue = 30;
277 break;
278
279 case 8:
280 TimeValue = 35;
281 break;
282
283 case 9:
284 TimeValue = 40;
285 break;
286
287 case 10:
288 TimeValue = 45;
289 break;
290
291 case 11:
292 TimeValue = 50;
293 break;
294
295 case 12:
296 TimeValue = 55;
297 break;
298
299 case 13:
300 TimeValue = 60;
301 break;
302
303 case 14:
304 TimeValue = 70;
305 break;
306
307 case 15:
308 TimeValue = 80;
309 break;
310
311 default:
312 DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
313 ASSERT(FALSE);
314 }
315
316 Frequency = TransferRateValue * TimeValue/10;
317
318 //Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
319 *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
320
321 DEBUG ((EFI_D_INFO, "MaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", MaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
322 }
323
324
325 VOID
326 GetCardConfigurationData (
327 VOID
328 )
329 {
330 UINTN BlockSize;
331 UINTN NumBlocks;
332 UINTN ClockFrequencySelect;
333
334 //Calculate BlockSize and Total number of blocks in the detected card.
335 GetBlockInformation(&BlockSize, &NumBlocks);
336 gCardInfo.BlockSize = BlockSize;
337 gCardInfo.NumBlocks = NumBlocks;
338
339 //Calculate Card clock divider value.
340 CalculateCardCLKD(&ClockFrequencySelect);
341 gCardInfo.ClockFrequencySelect = ClockFrequencySelect;
342 }
343
344
345 EFI_STATUS
346 InitializeMMCHS (
347 VOID
348 )
349 {
350 UINT8 Data = 0;
351 EFI_STATUS Status;
352
353 //Select Device group to belong to P1 device group in Power IC.
354 Data = DEV_GRP_P1;
355 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
356 ASSERT_EFI_ERROR(Status);
357
358 //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
359 Data = VSEL_3_00V;
360 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
361 ASSERT_EFI_ERROR(Status);
362
363 //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
364 MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
365
366 // Enable WP GPIO
367 MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
368
369 // Enable Card Detect
370 Data = CARD_DETECT_ENABLE;
371 gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
372
373
374 return Status;
375 }
376
377
378 EFI_STATUS
379 PerformCardIdenfication (
380 VOID
381 )
382 {
383 EFI_STATUS Status;
384 UINTN CmdArgument = 0;
385 UINTN Response = 0;
386 UINTN RetryCount = 0;
387 BOOLEAN SDCmd8Supported = FALSE;
388
389 //Enable interrupts.
390 MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
391 CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
392
393 //Controller INIT procedure start.
394 MmioOr32 (MMCHS_CON, INIT);
395 MmioWrite32 (MMCHS_CMD, 0x00000000);
396 while (!(MmioRead32 (MMCHS_STAT) & CC));
397
398 //Wait for 1 ms
399 gBS->Stall(1000);
400
401 //Set CC bit to 0x1 to clear the flag
402 MmioOr32 (MMCHS_STAT, CC);
403
404 //Retry INIT procedure.
405 MmioWrite32 (MMCHS_CMD, 0x00000000);
406 while (!(MmioRead32 (MMCHS_STAT) & CC));
407
408 //End initialization sequence
409 MmioAnd32 (MMCHS_CON, ~INIT);
410
411 MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
412
413 //Change clock frequency to 400KHz to fit protocol
414 UpdateMMCHSClkFrequency(CLKD_400KHZ);
415
416 MmioOr32 (MMCHS_CON, OD);
417
418 //Send CMD0 command.
419 Status = SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
420 if (EFI_ERROR(Status)) {
421 DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
422 return Status;
423 }
424
425 DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 (MMCHS_RSP10)));
426
427 //Send CMD5 command.
428 Status = SendCmd (CMD5, CMD5_INT_EN, CmdArgument);
429 if (Status == EFI_SUCCESS) {
430 DEBUG ((EFI_D_ERROR, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
431 DEBUG ((EFI_D_INFO, "CMD5 response: %x\n", MmioRead32 (MMCHS_RSP10)));
432 //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
433 return EFI_UNSUPPORTED;
434 } else {
435 DEBUG ((EFI_D_INFO, "CMD5 fails. Not an SDIO card.\n"));
436 }
437
438 MmioOr32 (MMCHS_SYSCTL, SRC);
439 gBS->Stall(1000);
440 while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
441
442 //Send CMD8 command. (New v2.00 command for Voltage check)
443 //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
444 //MMC & SD1.1 card will fail this command.
445 CmdArgument = CMD8_ARG;
446 Status = SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
447 if (Status == EFI_SUCCESS) {
448 Response = MmioRead32 (MMCHS_RSP10);
449 DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
450 if (Response != CmdArgument) {
451 return EFI_DEVICE_ERROR;
452 }
453 DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
454 SDCmd8Supported = TRUE; //Supports high capacity.
455 } else {
456 DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
457 }
458
459 MmioOr32 (MMCHS_SYSCTL, SRC);
460 gBS->Stall(1000);
461 while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
462
463 //Poll till card is busy
464 while (RetryCount < MAX_RETRY_COUNT) {
465 //Send CMD55 command.
466 CmdArgument = 0;
467 Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
468 if (Status == EFI_SUCCESS) {
469 DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 (MMCHS_RSP10)));
470 gCardInfo.CardType = SD_CARD;
471 } else {
472 DEBUG ((EFI_D_INFO, "CMD55 fails.\n"));
473 gCardInfo.CardType = MMC_CARD;
474 }
475
476 //Send appropriate command for the card type which got detected.
477 if (gCardInfo.CardType == SD_CARD) {
478 CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
479
480 //Set HCS bit.
481 if (SDCmd8Supported) {
482 CmdArgument |= HCS;
483 }
484
485 Status = SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
486 if (EFI_ERROR(Status)) {
487 DEBUG ((EFI_D_INFO, "ACMD41 fails.\n"));
488 return Status;
489 }
490 ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 (MMCHS_RSP10);
491 DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
492 } else if (gCardInfo.CardType == MMC_CARD) {
493 CmdArgument = 0;
494 Status = SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
495 if (EFI_ERROR(Status)) {
496 DEBUG ((EFI_D_INFO, "CMD1 fails.\n"));
497 return Status;
498 }
499 Response = MmioRead32 (MMCHS_RSP10);
500 DEBUG ((EFI_D_INFO, "MMC card detected.. CMD1 response: %x\n", Response));
501
502 //NOTE: For now, I am skipping this since I only have an SD card.
503 //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
504 return EFI_UNSUPPORTED; //For now, MMC is not supported.
505 }
506
507 //Poll the card until it is out of its power-up sequence.
508 if (gCardInfo.OCRData.Busy == 1) {
509
510 if (SDCmd8Supported) {
511 gCardInfo.CardType = SD_CARD_2;
512 }
513
514 //Card is ready. Check CCS (Card capacity status) bit (bit#30).
515 //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
516 if (gCardInfo.OCRData.AccessMode & BIT1) {
517 gCardInfo.CardType = SD_CARD_2_HIGH;
518 DEBUG ((EFI_D_INFO, "High capacity card.\n"));
519 } else {
520 DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
521 }
522
523 break;
524 }
525
526 gBS->Stall(1000);
527 RetryCount++;
528 }
529
530 if (RetryCount == MAX_RETRY_COUNT) {
531 DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
532 return EFI_TIMEOUT;
533 }
534
535 //Read CID data.
536 CmdArgument = 0;
537 Status = SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
538 if (EFI_ERROR(Status)) {
539 DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
540 return Status;
541 }
542
543 DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
544
545 //Parse CID register data.
546 ParseCardCIDData(MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76));
547
548 //Read RCA
549 CmdArgument = 0;
550 Status = SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
551 if (EFI_ERROR(Status)) {
552 DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
553 return Status;
554 }
555
556 //Set RCA for the detected card. RCA is CMD3 response.
557 gCardInfo.RCA = (MmioRead32 (MMCHS_RSP10) >> 16);
558 DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
559
560 //MMC Bus setting change after card identification.
561 MmioAnd32 (MMCHS_CON, ~OD);
562 MmioOr32 (MMCHS_HCTL, SDVS_3_0_V);
563 UpdateMMCHSClkFrequency(CLKD_400KHZ); //Set the clock frequency to 400KHz.
564
565 return EFI_SUCCESS;
566 }
567
568
569 EFI_STATUS
570 GetCardSpecificData (
571 VOID
572 )
573 {
574 EFI_STATUS Status;
575 UINTN CmdArgument;
576
577 //Send CMD9 to retrieve CSD.
578 CmdArgument = gCardInfo.RCA << 16;
579 Status = SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
580 if (EFI_ERROR(Status)) {
581 DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
582 return Status;
583 }
584
585 //Populate 128-bit CSD register data.
586 ((UINT32 *)&(gCardInfo.CSDData))[0] = MmioRead32 (MMCHS_RSP10);
587 ((UINT32 *)&(gCardInfo.CSDData))[1] = MmioRead32 (MMCHS_RSP32);
588 ((UINT32 *)&(gCardInfo.CSDData))[2] = MmioRead32 (MMCHS_RSP54);
589 ((UINT32 *)&(gCardInfo.CSDData))[3] = MmioRead32 (MMCHS_RSP76);
590
591 DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
592
593 //Calculate total number of blocks and max. data transfer rate supported by the detected card.
594 GetCardConfigurationData();
595
596 //Change MMCHS clock frequency to what detected card can support.
597 UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
598
599 return Status;
600 }
601
602
603 EFI_STATUS
604 PerformCardConfiguration (
605 VOID
606 )
607 {
608 UINTN CmdArgument = 0;
609 EFI_STATUS Status;
610
611 //Send CMD7
612 CmdArgument = gCardInfo.RCA << 16;
613 Status = SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
614 if (EFI_ERROR(Status)) {
615 DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
616 return Status;
617 }
618
619 //Send CMD16 to set the block length
620 CmdArgument = gCardInfo.BlockSize;
621 Status = SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
622 if (EFI_ERROR(Status)) {
623 DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
624 return Status;
625 }
626
627 return EFI_SUCCESS;
628 }
629
630
631 EFI_STATUS
632 ReadBlockData (
633 IN EFI_BLOCK_IO_PROTOCOL *This,
634 OUT VOID *Buffer
635 )
636 {
637 UINTN MmcStatus;
638 UINTN *DataBuffer = Buffer;
639 UINTN DataSize = This->Media->BlockSize/4;
640 UINTN Count;
641 UINTN RetryCount = 0;
642
643 //Check controller status to make sure there is no error.
644 while (RetryCount < MAX_RETRY_COUNT) {
645 do {
646 //Read Status.
647 MmcStatus = MmioRead32 (MMCHS_STAT);
648 } while(MmcStatus == 0);
649
650 //Check if Buffer read ready (BRR) bit is set?
651 if (MmcStatus & BRR) {
652
653 //Clear BRR bit
654 MmioOr32 (MMCHS_STAT, BRR);
655
656 //Read block worth of data.
657 for (Count = 0; Count < DataSize; Count++) {
658 *DataBuffer++ = MmioRead32 (MMCHS_DATA);
659 }
660 break;
661 }
662 RetryCount++;
663 }
664
665 if (RetryCount == MAX_RETRY_COUNT) {
666 return EFI_TIMEOUT;
667 }
668
669 return EFI_SUCCESS;
670 }
671
672
673 EFI_STATUS
674 WriteBlockData (
675 IN EFI_BLOCK_IO_PROTOCOL *This,
676 OUT VOID *Buffer
677 )
678 {
679 UINTN MmcStatus;
680 UINTN *DataBuffer = Buffer;
681 UINTN DataSize = This->Media->BlockSize/4;
682 UINTN Count;
683 UINTN RetryCount = 0;
684
685 //Check controller status to make sure there is no error.
686 while (RetryCount < MAX_RETRY_COUNT) {
687 do {
688 //Read Status.
689 MmcStatus = MmioRead32 (MMCHS_STAT);
690 } while(MmcStatus == 0);
691
692 //Check if Buffer write ready (BWR) bit is set?
693 if (MmcStatus & BWR) {
694
695 //Clear BWR bit
696 MmioOr32 (MMCHS_STAT, BWR);
697
698 //Write block worth of data.
699 for (Count = 0; Count < DataSize; Count++) {
700 MmioWrite32 (MMCHS_DATA, *DataBuffer++);
701 }
702
703 break;
704 }
705 RetryCount++;
706 }
707
708 if (RetryCount == MAX_RETRY_COUNT) {
709 return EFI_TIMEOUT;
710 }
711
712 return EFI_SUCCESS;
713 }
714
715
716 EFI_STATUS
717 TransferBlockData (
718 IN EFI_BLOCK_IO_PROTOCOL *This,
719 OUT VOID *Buffer,
720 IN OPERATION_TYPE OperationType
721 )
722 {
723 EFI_STATUS Status;
724 UINTN MmcStatus;
725 UINTN RetryCount = 0;
726
727 //Read or Write data.
728 if (OperationType == READ) {
729 Status = ReadBlockData(This, Buffer);
730 if (EFI_ERROR(Status)) {
731 DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
732 return Status;
733 }
734 } else if (OperationType == WRITE) {
735 Status = WriteBlockData(This, Buffer);
736 if (EFI_ERROR(Status)) {
737 DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
738 return Status;
739 }
740 }
741
742 //Check for the Transfer completion.
743 while (RetryCount < MAX_RETRY_COUNT) {
744 //Read Status
745 do {
746 MmcStatus = MmioRead32 (MMCHS_STAT);
747 } while (MmcStatus == 0);
748
749 //Check if Transfer complete (TC) bit is set?
750 if (MmcStatus & TC) {
751 break;
752 } else {
753 DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
754 //Check if DEB, DCRC or DTO interrupt occured.
755 if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
756 //There was an error during the data transfer.
757
758 //Set SRD bit to 1 and wait until it return to 0x0.
759 MmioOr32 (MMCHS_SYSCTL, SRD);
760 while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
761
762 return EFI_DEVICE_ERROR;
763 }
764 }
765 RetryCount++;
766 }
767
768 if (RetryCount == MAX_RETRY_COUNT) {
769 DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
770 return EFI_TIMEOUT;
771 }
772
773 return EFI_SUCCESS;
774 }
775
776 BOOLEAN
777 CardPresent (
778 VOID
779 )
780 {
781 EFI_STATUS Status;
782 UINT8 Data;
783
784 //
785 // Card detect is a GPIO0 on the TPS65950
786 //
787 Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
788 if (EFI_ERROR (Status)) {
789 return FALSE;
790 }
791
792 if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
793 // No Card present
794 return FALSE;
795 } else {
796 return TRUE;
797 }
798 }
799
800 EFI_STATUS
801 DetectCard (
802 VOID
803 )
804 {
805 EFI_STATUS Status;
806
807 if (!CardPresent ()) {
808 return EFI_NO_MEDIA;
809 }
810
811 //Initialize MMC host controller clocks.
812 Status = InitializeMMCHS ();
813 if (EFI_ERROR(Status)) {
814 DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
815 return Status;
816 }
817
818 //Software reset of the MMCHS host controller.
819 MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
820 gBS->Stall(1000);
821 while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
822
823 //Soft reset for all.
824 MmioWrite32 (MMCHS_SYSCTL, SRA);
825 gBS->Stall(1000);
826 while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
827
828 //Voltage capabilities initialization. Activate VS18 and VS30.
829 MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
830
831 //Wakeup configuration
832 MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
833 MmioOr32 (MMCHS_HCTL, IWE);
834
835 //MMCHS Controller default initialization
836 MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
837
838 MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
839
840 //Enable internal clock
841 MmioOr32 (MMCHS_SYSCTL, ICE);
842
843 //Set the clock frequency to 80KHz.
844 UpdateMMCHSClkFrequency (CLKD_80KHZ);
845
846 //Enable SD bus power.
847 MmioOr32 (MMCHS_HCTL, (SDBP_ON));
848
849 //Poll till SD bus power bit is set.
850 while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
851
852 //Card idenfication
853 Status = PerformCardIdenfication ();
854 if (EFI_ERROR(Status)) {
855 DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
856 return Status;
857 }
858
859 //Get CSD (Card specific data) for the detected card.
860 Status = GetCardSpecificData();
861 if (EFI_ERROR(Status)) {
862 return Status;
863 }
864
865 //Configure the card in data transfer mode.
866 Status = PerformCardConfiguration();
867 if (EFI_ERROR(Status)) {
868 return Status;
869 }
870
871 //Patch the Media structure.
872 gMMCHSMedia.LastBlock = (gCardInfo.NumBlocks - 1);
873 gMMCHSMedia.BlockSize = gCardInfo.BlockSize;
874 gMMCHSMedia.ReadOnly = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
875 gMMCHSMedia.MediaPresent = TRUE;
876 gMMCHSMedia.MediaId++;
877 gMediaChange = FALSE;
878
879 return Status;
880 }
881
882
883 EFI_STATUS
884 SdReadWrite (
885 IN EFI_BLOCK_IO_PROTOCOL *This,
886 IN UINTN Lba,
887 OUT VOID *Buffer,
888 IN UINTN BufferSize,
889 IN OPERATION_TYPE OperationType
890 )
891 {
892 EFI_STATUS Status = EFI_SUCCESS;
893 UINTN RetryCount = 0;
894 UINTN NumBlocks;
895 UINTN Cmd = 0;
896 UINTN CmdInterruptEnable = 0;
897 UINTN CmdArgument = 0;
898 EFI_TPL OldTpl;
899 BOOLEAN MediaPresentLastTime;
900 BOOLEAN Update;
901
902 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
903
904
905 if (Buffer == NULL) {
906 Status = EFI_INVALID_PARAMETER;
907 goto Done;
908 }
909
910 Update = FALSE;
911 MediaPresentLastTime = gMMCHSMedia.MediaPresent;
912
913 if (gMediaChange) {
914 Status = DetectCard ();
915 if (EFI_ERROR (Status)) {
916 // We detected a removal
917 gMMCHSMedia.MediaPresent = FALSE;
918 gMMCHSMedia.LastBlock = 0;
919 gMMCHSMedia.BlockSize = 512; // Should be zero but there is a bug in DiskIo
920 gMMCHSMedia.ReadOnly = FALSE;
921 } else {
922 Update = TRUE;
923 }
924 gMediaChange = FALSE;
925 } else if (!gMMCHSMedia.MediaPresent) {
926 Status = EFI_NO_MEDIA;
927 goto Done;
928 }
929
930 if ((MediaPresentLastTime != gMMCHSMedia.MediaPresent) || Update) {
931 gBS->ReinstallProtocolInterface (
932 gImageHandle,
933 &gEfiBlockIoProtocolGuid,
934 &gBlockIo,
935 &gBlockIo
936 );
937 }
938
939 if (EFI_ERROR (Status)) {
940 goto Done;
941 }
942
943 if (Lba > This->Media->LastBlock) {
944 Status = EFI_INVALID_PARAMETER;
945 goto Done;
946 }
947
948 if ((BufferSize % This->Media->BlockSize) != 0) {
949 Status = EFI_BAD_BUFFER_SIZE;
950 goto Done;
951 }
952
953 //Check if the data lines are not in use.
954 while ((RetryCount++ < MAX_RETRY_COUNT) && ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) != DATI_ALLOWED));
955 if (RetryCount == MAX_RETRY_COUNT) {
956 Status = EFI_TIMEOUT;
957 goto Done;
958 }
959
960 //Populate the command information based on the operation type.
961 if (OperationType == READ) {
962 Cmd = CMD17; //Single block read
963 CmdInterruptEnable = CMD17_INT_EN;
964 } else if (OperationType == WRITE) {
965 Cmd = CMD24; //Single block write
966 CmdInterruptEnable = CMD24_INT_EN;
967 }
968
969 //Calculate total number of blocks its going to read.
970 NumBlocks = (BufferSize + (This->Media->BlockSize - 1))/This->Media->BlockSize;
971
972 //Set command argument based on the card access mode (Byte mode or Block mode)
973 if (gCardInfo.OCRData.AccessMode & BIT1) {
974 CmdArgument = (UINTN)Lba;
975 } else {
976 CmdArgument = (UINTN)Lba * This->Media->BlockSize;
977 }
978
979 while(NumBlocks) {
980 //Send Command.
981 Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
982 if (EFI_ERROR(Status)) {
983 DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
984 goto Done;
985 }
986
987 //Transfer a block worth of data.
988 Status = TransferBlockData(This, Buffer, OperationType);
989 if (EFI_ERROR(Status)) {
990 DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
991 goto Done;
992 }
993
994 //Adjust command argument.
995 if (gCardInfo.OCRData.AccessMode & BIT1) {
996 CmdArgument++; //Increase BlockIndex by one.
997 } else {
998 CmdArgument += This->Media->BlockSize; //Increase BlockIndex by BlockSize
999 }
1000
1001 //Adjust Buffer.
1002 Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
1003 NumBlocks--;
1004 }
1005
1006 Done:
1007 gBS->RestoreTPL (OldTpl);
1008 return Status;
1009 }
1010
1011
1012 /**
1013 Reset the Block Device.
1014
1015 @param This Indicates a pointer to the calling context.
1016 @param ExtendedVerification Driver may perform diagnostics on reset.
1017
1018 @retval EFI_SUCCESS The device was reset.
1019 @retval EFI_DEVICE_ERROR The device is not functioning properly and could
1020 not be reset.
1021
1022 **/
1023 EFI_STATUS
1024 EFIAPI
1025 MMCHSReset (
1026 IN EFI_BLOCK_IO_PROTOCOL *This,
1027 IN BOOLEAN ExtendedVerification
1028 )
1029 {
1030 return EFI_SUCCESS;
1031 }
1032
1033
1034 /**
1035 Read BufferSize bytes from Lba into Buffer.
1036
1037 @param This Indicates a pointer to the calling context.
1038 @param MediaId Id of the media, changes every time the media is replaced.
1039 @param Lba The starting Logical Block Address to read from
1040 @param BufferSize Size of Buffer, must be a multiple of device block size.
1041 @param Buffer A pointer to the destination buffer for the data. The caller is
1042 responsible for either having implicit or explicit ownership of the buffer.
1043
1044 @retval EFI_SUCCESS The data was read correctly from the device.
1045 @retval EFI_DEVICE_ERROR The device reported an error while performing the read.
1046 @retval EFI_NO_MEDIA There is no media in the device.
1047 @retval EFI_MEDIA_CHANGED The MediaId does not matched the current device.
1048 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1049 @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1050 or the buffer is not on proper alignment.
1051 EFI_STATUS
1052
1053 **/
1054 EFI_STATUS
1055 EFIAPI
1056 MMCHSReadBlocks (
1057 IN EFI_BLOCK_IO_PROTOCOL *This,
1058 IN UINT32 MediaId,
1059 IN EFI_LBA Lba,
1060 IN UINTN BufferSize,
1061 OUT VOID *Buffer
1062 )
1063 {
1064 EFI_STATUS Status;
1065
1066 //Perform Read operation.
1067 Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
1068
1069 return Status;
1070 }
1071
1072
1073 /**
1074 Write BufferSize bytes from Lba into Buffer.
1075
1076 @param This Indicates a pointer to the calling context.
1077 @param MediaId The media ID that the write request is for.
1078 @param Lba The starting logical block address to be written. The caller is
1079 responsible for writing to only legitimate locations.
1080 @param BufferSize Size of Buffer, must be a multiple of device block size.
1081 @param Buffer A pointer to the source buffer for the data.
1082
1083 @retval EFI_SUCCESS The data was written correctly to the device.
1084 @retval EFI_WRITE_PROTECTED The device can not be written to.
1085 @retval EFI_DEVICE_ERROR The device reported an error while performing the write.
1086 @retval EFI_NO_MEDIA There is no media in the device.
1087 @retval EFI_MEDIA_CHNAGED The MediaId does not matched the current device.
1088 @retval EFI_BAD_BUFFER_SIZE The Buffer was not a multiple of the block size of the device.
1089 @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1090 or the buffer is not on proper alignment.
1091
1092 **/
1093 EFI_STATUS
1094 EFIAPI
1095 MMCHSWriteBlocks (
1096 IN EFI_BLOCK_IO_PROTOCOL *This,
1097 IN UINT32 MediaId,
1098 IN EFI_LBA Lba,
1099 IN UINTN BufferSize,
1100 IN VOID *Buffer
1101 )
1102 {
1103 EFI_STATUS Status;
1104
1105 //Perform write operation.
1106 Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
1107
1108 return Status;
1109 }
1110
1111
1112 /**
1113 Flush the Block Device.
1114
1115 @param This Indicates a pointer to the calling context.
1116
1117 @retval EFI_SUCCESS All outstanding data was written to the device
1118 @retval EFI_DEVICE_ERROR The device reported an error while writting back the data
1119 @retval EFI_NO_MEDIA There is no media in the device.
1120
1121 **/
1122 EFI_STATUS
1123 EFIAPI
1124 MMCHSFlushBlocks (
1125 IN EFI_BLOCK_IO_PROTOCOL *This
1126 )
1127 {
1128 return EFI_SUCCESS;
1129 }
1130
1131
1132 EFI_BLOCK_IO_PROTOCOL gBlockIo = {
1133 EFI_BLOCK_IO_INTERFACE_REVISION, // Revision
1134 &gMMCHSMedia, // *Media
1135 MMCHSReset, // Reset
1136 MMCHSReadBlocks, // ReadBlocks
1137 MMCHSWriteBlocks, // WriteBlocks
1138 MMCHSFlushBlocks // FlushBlocks
1139 };
1140
1141
1142 /**
1143 Timer callback to convert card present hardware into a boolean that indicates
1144 a media change event has happened. If you just check the GPIO you could see
1145 card 1 and then check again after card 1 was removed and card 2 was inserted
1146 and you would still see media present. Thus you need the timer tick to catch
1147 the toggle event.
1148
1149 @param Event Event whose notification function is being invoked.
1150 @param Context The pointer to the notification function's context,
1151 which is implementation-dependent. Not used.
1152
1153 **/
1154 VOID
1155 EFIAPI
1156 TimerCallback (
1157 IN EFI_EVENT Event,
1158 IN VOID *Context
1159 )
1160 {
1161 BOOLEAN Present;
1162
1163 Present = CardPresent ();
1164 if (gMMCHSMedia.MediaPresent) {
1165 if (!Present && !gMediaChange) {
1166 gMediaChange = TRUE;
1167 }
1168 } else {
1169 if (Present && !gMediaChange) {
1170 gMediaChange = TRUE;
1171 }
1172 }
1173 }
1174
1175
1176 EFI_STATUS
1177 EFIAPI
1178 MMCHSInitialize (
1179 IN EFI_HANDLE ImageHandle,
1180 IN EFI_SYSTEM_TABLE *SystemTable
1181 )
1182 {
1183 EFI_STATUS Status;
1184
1185 Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
1186 ASSERT_EFI_ERROR(Status);
1187
1188 ZeroMem (&gCardInfo, sizeof (CARD_INFO));
1189
1190 Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
1191 ASSERT_EFI_ERROR (Status);
1192
1193 Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, 1000000); // make me a PCD
1194 ASSERT_EFI_ERROR (Status);
1195
1196 //Publish BlockIO.
1197 Status = gBS->InstallMultipleProtocolInterfaces (
1198 &ImageHandle,
1199 &gEfiBlockIoProtocolGuid, &gBlockIo,
1200 &gEfiDevicePathProtocolGuid, &gMmcHsDevicePath,
1201 NULL
1202 );
1203 return Status;
1204 }