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 "MMCHS.h"
25 
26 EFI_BLOCK_IO_MEDIA gMMCHSMedia = {
27   SIGNATURE_32('s','d','i','o'),            // MediaId
28   TRUE,                                     // RemovableMedia
29   FALSE,                                    // MediaPresent
30   FALSE,                                    // LogicalPartition
31   FALSE,                                    // ReadOnly
32   FALSE,                                    // WriteCaching
33   512,                                      // BlockSize
34   4,                                        // IoAlign
35   0,                                        // Pad
36   0                                         // LastBlock
37 };
38 
39 typedef struct {
40   VENDOR_DEVICE_PATH  Mmc;
41   EFI_DEVICE_PATH     End;
42 } MMCHS_DEVICE_PATH;
43 
44 MMCHS_DEVICE_PATH gMmcHsDevicePath = {
45   {
46     {
47       HARDWARE_DEVICE_PATH,
48       HW_VENDOR_DP,
49       {
50         (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
51         (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
52       },
53     },
54     { 0xb615f1f5, 0x5088, 0x43cd, { 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00 } },
55   },
56   {
57     END_DEVICE_PATH_TYPE,
58     END_ENTIRE_DEVICE_PATH_SUBTYPE,
59     { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
60   }
61 };
62 
63 CARD_INFO                  gCardInfo;
64 EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
65 EFI_EVENT                  gTimerEvent;
66 BOOLEAN                    gMediaChange = FALSE;
67 
68 //
69 // Internal Functions
70 //
71 
72 
73 VOID
ParseCardCIDData(UINT32 Response0,UINT32 Response1,UINT32 Response2,UINT32 Response3)74 ParseCardCIDData (
75   UINT32 Response0,
76   UINT32 Response1,
77   UINT32 Response2,
78   UINT32 Response3
79   )
80 {
81   gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
82   gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
83   gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
84   gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
85   gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
86   gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
87   gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
88   gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
89   gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
90   gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
91 }
92 
93 
94 VOID
UpdateMMCHSClkFrequency(UINTN NewCLKD)95 UpdateMMCHSClkFrequency (
96   UINTN NewCLKD
97   )
98 {
99   //Set Clock enable to 0x0 to not provide the clock to the card
100   MmioAnd32 (MMCHS_SYSCTL, ~CEN);
101 
102   //Set new clock frequency.
103   MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
104 
105   //Poll till Internal Clock Stable
106   while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
107 
108   //Set Clock enable to 0x1 to provide the clock to the card
109   MmioOr32 (MMCHS_SYSCTL, CEN);
110 }
111 
112 
113 EFI_STATUS
SendCmd(UINTN Cmd,UINTN CmdInterruptEnableVal,UINTN CmdArgument)114 SendCmd (
115   UINTN Cmd,
116   UINTN CmdInterruptEnableVal,
117   UINTN CmdArgument
118   )
119 {
120   UINTN MmcStatus;
121   UINTN RetryCount = 0;
122 
123   //Check if command line is in use or not. Poll till command line is available.
124   while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
125 
126   //Provide the block size.
127   MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
128 
129   //Setting Data timeout counter value to max value.
130   MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
131 
132   //Clear Status register.
133   MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
134 
135   //Set command argument register
136   MmioWrite32 (MMCHS_ARG, CmdArgument);
137 
138   //Enable interrupt enable events to occur
139   MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
140 
141   //Send a command
142   MmioWrite32 (MMCHS_CMD, Cmd);
143 
144   //Check for the command status.
145   while (RetryCount < MAX_RETRY_COUNT) {
146     do {
147       MmcStatus = MmioRead32 (MMCHS_STAT);
148     } while (MmcStatus == 0);
149 
150     //Read status of command response
151     if ((MmcStatus & ERRI) != 0) {
152 
153       //Perform soft-reset for mmci_cmd line.
154       MmioOr32 (MMCHS_SYSCTL, SRC);
155       while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
156 
157       DEBUG ((EFI_D_INFO, "MmcStatus: %x\n", MmcStatus));
158       return EFI_DEVICE_ERROR;
159     }
160 
161     //Check if command is completed.
162     if ((MmcStatus & CC) == CC) {
163       MmioWrite32 (MMCHS_STAT, CC);
164       break;
165     }
166 
167     RetryCount++;
168   }
169 
170   if (RetryCount == MAX_RETRY_COUNT) {
171     return EFI_TIMEOUT;
172   }
173 
174   return EFI_SUCCESS;
175 }
176 
177 
178 VOID
GetBlockInformation(UINTN * BlockSize,UINTN * NumBlocks)179 GetBlockInformation (
180   UINTN *BlockSize,
181   UINTN *NumBlocks
182   )
183 {
184   CSD_SDV2 *CsdSDV2Data;
185   UINTN    CardSize;
186 
187   if (gCardInfo.CardType == SD_CARD_2_HIGH) {
188     CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
189 
190     //Populate BlockSize.
191     *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
192 
193     //Calculate Total number of blocks.
194     CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
195     *NumBlocks = ((CardSize + 1) * 1024);
196   } else {
197     //Populate BlockSize.
198     *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
199 
200     //Calculate Total number of blocks.
201     CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
202     *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
203   }
204 
205   //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
206   if (*BlockSize > 512) {
207     *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
208     *BlockSize = 512;
209   }
210 
211   DEBUG ((EFI_D_INFO, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
212 }
213 
214 
215 VOID
CalculateCardCLKD(UINTN * ClockFrequencySelect)216 CalculateCardCLKD (
217   UINTN *ClockFrequencySelect
218   )
219 {
220   UINT8    MaxDataTransferRate;
221   UINTN    TransferRateValue = 0;
222   UINTN    TimeValue = 0 ;
223   UINTN    Frequency = 0;
224 
225   MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
226 
227   // For SD Cards  we would need to send CMD6 to set
228   // speeds abouve 25MHz. High Speed mode 50 MHz and up
229 
230   //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
231   switch (MaxDataTransferRate & 0x7) {
232     case 0:
233       TransferRateValue = 100 * 1000;
234       break;
235 
236     case 1:
237       TransferRateValue = 1 * 1000 * 1000;
238       break;
239 
240     case 2:
241       TransferRateValue = 10 * 1000 * 1000;
242       break;
243 
244     case 3:
245       TransferRateValue = 100 * 1000 * 1000;
246       break;
247 
248     default:
249       DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
250       ASSERT(FALSE);
251   }
252 
253   //Calculate Time value (Bits 6:3 of TRAN_SPEED)
254   switch ((MaxDataTransferRate >> 3) & 0xF) {
255     case 1:
256       TimeValue = 10;
257       break;
258 
259     case 2:
260       TimeValue = 12;
261       break;
262 
263     case 3:
264       TimeValue = 13;
265       break;
266 
267     case 4:
268       TimeValue = 15;
269       break;
270 
271     case 5:
272       TimeValue = 20;
273       break;
274 
275     case 6:
276       TimeValue = 25;
277       break;
278 
279     case 7:
280       TimeValue = 30;
281       break;
282 
283     case 8:
284       TimeValue = 35;
285       break;
286 
287     case 9:
288       TimeValue = 40;
289       break;
290 
291     case 10:
292       TimeValue = 45;
293       break;
294 
295     case 11:
296       TimeValue = 50;
297       break;
298 
299     case 12:
300       TimeValue = 55;
301       break;
302 
303     case 13:
304       TimeValue = 60;
305       break;
306 
307     case 14:
308       TimeValue = 70;
309       break;
310 
311     case 15:
312       TimeValue = 80;
313       break;
314 
315     default:
316       DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
317       ASSERT(FALSE);
318   }
319 
320   Frequency = TransferRateValue * TimeValue/10;
321 
322   //Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
323   *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
324 
325   DEBUG ((EFI_D_INFO, "MaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", MaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
326 }
327 
328 
329 VOID
GetCardConfigurationData(VOID)330 GetCardConfigurationData (
331   VOID
332   )
333 {
334   UINTN  BlockSize;
335   UINTN  NumBlocks;
336   UINTN  ClockFrequencySelect;
337 
338   //Calculate BlockSize and Total number of blocks in the detected card.
339   GetBlockInformation(&BlockSize, &NumBlocks);
340   gCardInfo.BlockSize = BlockSize;
341   gCardInfo.NumBlocks = NumBlocks;
342 
343   //Calculate Card clock divider value.
344   CalculateCardCLKD(&ClockFrequencySelect);
345   gCardInfo.ClockFrequencySelect = ClockFrequencySelect;
346 }
347 
348 
349 EFI_STATUS
InitializeMMCHS(VOID)350 InitializeMMCHS (
351   VOID
352   )
353 {
354   UINT8      Data = 0;
355   EFI_STATUS Status;
356 
357   //Select Device group to belong to P1 device group in Power IC.
358   Data = DEV_GRP_P1;
359   Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
360   ASSERT_EFI_ERROR(Status);
361 
362   //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
363   Data = VSEL_3_00V;
364   Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
365   ASSERT_EFI_ERROR(Status);
366 
367   //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
368   MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
369 
370   // Enable WP GPIO
371   MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
372 
373   // Enable Card Detect
374   Data = CARD_DETECT_ENABLE;
375   gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
376 
377 
378   return Status;
379 }
380 
381 
382 EFI_STATUS
PerformCardIdenfication(VOID)383 PerformCardIdenfication (
384   VOID
385   )
386 {
387   EFI_STATUS Status;
388   UINTN      CmdArgument = 0;
389   UINTN      Response = 0;
390   UINTN      RetryCount = 0;
391   BOOLEAN    SDCmd8Supported = FALSE;
392 
393   //Enable interrupts.
394   MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
395     CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
396 
397   //Controller INIT procedure start.
398   MmioOr32 (MMCHS_CON, INIT);
399   MmioWrite32 (MMCHS_CMD, 0x00000000);
400   while (!(MmioRead32 (MMCHS_STAT) & CC));
401 
402   //Wait for 1 ms
403   gBS->Stall(1000);
404 
405   //Set CC bit to 0x1 to clear the flag
406   MmioOr32 (MMCHS_STAT, CC);
407 
408   //Retry INIT procedure.
409   MmioWrite32 (MMCHS_CMD, 0x00000000);
410   while (!(MmioRead32 (MMCHS_STAT) & CC));
411 
412   //End initialization sequence
413   MmioAnd32 (MMCHS_CON, ~INIT);
414 
415   MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
416 
417   //Change clock frequency to 400KHz to fit protocol
418   UpdateMMCHSClkFrequency(CLKD_400KHZ);
419 
420   MmioOr32 (MMCHS_CON, OD);
421 
422   //Send CMD0 command.
423   Status = SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
424   if (EFI_ERROR(Status)) {
425     DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
426     return Status;
427   }
428 
429   DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 (MMCHS_RSP10)));
430 
431   //Send CMD5 command.
432   Status = SendCmd (CMD5, CMD5_INT_EN, CmdArgument);
433   if (Status == EFI_SUCCESS) {
434     DEBUG ((EFI_D_ERROR, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
435     DEBUG ((EFI_D_INFO, "CMD5 response: %x\n", MmioRead32 (MMCHS_RSP10)));
436     //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
437     return EFI_UNSUPPORTED;
438   } else {
439     DEBUG ((EFI_D_INFO, "CMD5 fails. Not an SDIO card.\n"));
440   }
441 
442   MmioOr32 (MMCHS_SYSCTL, SRC);
443   gBS->Stall(1000);
444   while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
445 
446   //Send CMD8 command. (New v2.00 command for Voltage check)
447   //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
448   //MMC & SD1.1 card will fail this command.
449   CmdArgument = CMD8_ARG;
450   Status = SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
451   if (Status == EFI_SUCCESS) {
452     Response = MmioRead32 (MMCHS_RSP10);
453     DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
454     if (Response != CmdArgument) {
455       return EFI_DEVICE_ERROR;
456     }
457     DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
458     SDCmd8Supported = TRUE; //Supports high capacity.
459   } else {
460     DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
461   }
462 
463   MmioOr32 (MMCHS_SYSCTL, SRC);
464   gBS->Stall(1000);
465   while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
466 
467   //Poll till card is busy
468   while (RetryCount < MAX_RETRY_COUNT) {
469     //Send CMD55 command.
470     CmdArgument = 0;
471     Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
472     if (Status == EFI_SUCCESS) {
473       DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 (MMCHS_RSP10)));
474       gCardInfo.CardType = SD_CARD;
475     } else {
476       DEBUG ((EFI_D_INFO, "CMD55 fails.\n"));
477       gCardInfo.CardType = MMC_CARD;
478     }
479 
480     //Send appropriate command for the card type which got detected.
481     if (gCardInfo.CardType == SD_CARD) {
482       CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
483 
484       //Set HCS bit.
485       if (SDCmd8Supported) {
486         CmdArgument |= HCS;
487       }
488 
489       Status = SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
490       if (EFI_ERROR(Status)) {
491         DEBUG ((EFI_D_INFO, "ACMD41 fails.\n"));
492         return Status;
493       }
494       ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 (MMCHS_RSP10);
495       DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
496     } else if (gCardInfo.CardType == MMC_CARD) {
497       CmdArgument = 0;
498       Status = SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
499       if (EFI_ERROR(Status)) {
500         DEBUG ((EFI_D_INFO, "CMD1 fails.\n"));
501         return Status;
502       }
503       Response = MmioRead32 (MMCHS_RSP10);
504       DEBUG ((EFI_D_INFO, "MMC card detected.. CMD1 response: %x\n", Response));
505 
506       //NOTE: For now, I am skipping this since I only have an SD card.
507       //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
508       return EFI_UNSUPPORTED; //For now, MMC is not supported.
509     }
510 
511     //Poll the card until it is out of its power-up sequence.
512     if (gCardInfo.OCRData.Busy == 1) {
513 
514       if (SDCmd8Supported) {
515         gCardInfo.CardType = SD_CARD_2;
516       }
517 
518       //Card is ready. Check CCS (Card capacity status) bit (bit#30).
519       //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
520       if (gCardInfo.OCRData.AccessMode & BIT1) {
521         gCardInfo.CardType = SD_CARD_2_HIGH;
522         DEBUG ((EFI_D_INFO, "High capacity card.\n"));
523       } else {
524         DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
525       }
526 
527       break;
528     }
529 
530     gBS->Stall(1000);
531     RetryCount++;
532   }
533 
534   if (RetryCount == MAX_RETRY_COUNT) {
535     DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
536     return EFI_TIMEOUT;
537   }
538 
539   //Read CID data.
540   CmdArgument = 0;
541   Status = SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
542   if (EFI_ERROR(Status)) {
543     DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
544     return Status;
545   }
546 
547   DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
548 
549   //Parse CID register data.
550   ParseCardCIDData(MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76));
551 
552   //Read RCA
553   CmdArgument = 0;
554   Status = SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
555   if (EFI_ERROR(Status)) {
556     DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
557     return Status;
558   }
559 
560   //Set RCA for the detected card. RCA is CMD3 response.
561   gCardInfo.RCA = (MmioRead32 (MMCHS_RSP10) >> 16);
562   DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
563 
564   //MMC Bus setting change after card identification.
565   MmioAnd32 (MMCHS_CON, ~OD);
566   MmioOr32 (MMCHS_HCTL, SDVS_3_0_V);
567   UpdateMMCHSClkFrequency(CLKD_400KHZ); //Set the clock frequency to 400KHz.
568 
569   return EFI_SUCCESS;
570 }
571 
572 
573 EFI_STATUS
GetCardSpecificData(VOID)574 GetCardSpecificData (
575   VOID
576   )
577 {
578   EFI_STATUS Status;
579   UINTN      CmdArgument;
580 
581   //Send CMD9 to retrieve CSD.
582   CmdArgument = gCardInfo.RCA << 16;
583   Status = SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
584   if (EFI_ERROR(Status)) {
585     DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
586     return Status;
587   }
588 
589   //Populate 128-bit CSD register data.
590   ((UINT32 *)&(gCardInfo.CSDData))[0] = MmioRead32 (MMCHS_RSP10);
591   ((UINT32 *)&(gCardInfo.CSDData))[1] = MmioRead32 (MMCHS_RSP32);
592   ((UINT32 *)&(gCardInfo.CSDData))[2] = MmioRead32 (MMCHS_RSP54);
593   ((UINT32 *)&(gCardInfo.CSDData))[3] = MmioRead32 (MMCHS_RSP76);
594 
595   DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
596 
597   //Calculate total number of blocks and max. data transfer rate supported by the detected card.
598   GetCardConfigurationData();
599 
600   return Status;
601 }
602 
603 
604 EFI_STATUS
PerformCardConfiguration(VOID)605 PerformCardConfiguration (
606   VOID
607   )
608 {
609   UINTN      CmdArgument = 0;
610   EFI_STATUS Status;
611 
612   //Send CMD7
613   CmdArgument = gCardInfo.RCA << 16;
614   Status = SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
615   if (EFI_ERROR(Status)) {
616     DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
617     return Status;
618   }
619 
620   if ((gCardInfo.CardType != UNKNOWN_CARD) && (gCardInfo.CardType != MMC_CARD)) {
621     // We could read SCR register, but SD Card Phys spec stats any SD Card shall
622     // set SCR.SD_BUS_WIDTHS to support 4-bit mode, so why bother?
623 
624     // Send ACMD6 (application specific commands must be prefixed with CMD55)
625     Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
626     if (!EFI_ERROR (Status)) {
627       // set device into 4-bit data bus mode
628       Status = SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
629       if (!EFI_ERROR (Status)) {
630         // Set host controler into 4-bit mode
631         MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
632         DEBUG ((EFI_D_INFO, "SD Memory Card set to 4-bit mode\n"));
633       }
634     }
635   }
636 
637   //Send CMD16 to set the block length
638   CmdArgument = gCardInfo.BlockSize;
639   Status = SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
640   if (EFI_ERROR(Status)) {
641     DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
642     return Status;
643   }
644 
645   //Change MMCHS clock frequency to what detected card can support.
646   UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
647 
648   return EFI_SUCCESS;
649 }
650 
651 
652 EFI_STATUS
ReadBlockData(IN EFI_BLOCK_IO_PROTOCOL * This,OUT VOID * Buffer)653 ReadBlockData (
654   IN  EFI_BLOCK_IO_PROTOCOL       *This,
655   OUT VOID                        *Buffer
656   )
657 {
658   UINTN MmcStatus;
659   UINTN *DataBuffer = Buffer;
660   UINTN DataSize = This->Media->BlockSize/4;
661   UINTN Count;
662   UINTN RetryCount = 0;
663 
664   //Check controller status to make sure there is no error.
665   while (RetryCount < MAX_RETRY_COUNT) {
666     do {
667       //Read Status.
668       MmcStatus = MmioRead32 (MMCHS_STAT);
669     } while(MmcStatus == 0);
670 
671     //Check if Buffer read ready (BRR) bit is set?
672     if (MmcStatus & BRR) {
673 
674       //Clear BRR bit
675       MmioOr32 (MMCHS_STAT, BRR);
676 
677       //Read block worth of data.
678       for (Count = 0; Count < DataSize; Count++) {
679         *DataBuffer++ = MmioRead32 (MMCHS_DATA);
680       }
681       break;
682     }
683     RetryCount++;
684   }
685 
686   if (RetryCount == MAX_RETRY_COUNT) {
687     return EFI_TIMEOUT;
688   }
689 
690   return EFI_SUCCESS;
691 }
692 
693 
694 EFI_STATUS
WriteBlockData(IN EFI_BLOCK_IO_PROTOCOL * This,OUT VOID * Buffer)695 WriteBlockData (
696   IN  EFI_BLOCK_IO_PROTOCOL       *This,
697   OUT VOID                        *Buffer
698   )
699 {
700   UINTN MmcStatus;
701   UINTN *DataBuffer = Buffer;
702   UINTN DataSize = This->Media->BlockSize/4;
703   UINTN Count;
704   UINTN RetryCount = 0;
705 
706   //Check controller status to make sure there is no error.
707   while (RetryCount < MAX_RETRY_COUNT) {
708     do {
709       //Read Status.
710       MmcStatus = MmioRead32 (MMCHS_STAT);
711     } while(MmcStatus == 0);
712 
713     //Check if Buffer write ready (BWR) bit is set?
714     if (MmcStatus & BWR) {
715 
716       //Clear BWR bit
717       MmioOr32 (MMCHS_STAT, BWR);
718 
719       //Write block worth of data.
720       for (Count = 0; Count < DataSize; Count++) {
721         MmioWrite32 (MMCHS_DATA, *DataBuffer++);
722       }
723 
724       break;
725     }
726     RetryCount++;
727   }
728 
729   if (RetryCount == MAX_RETRY_COUNT) {
730     return EFI_TIMEOUT;
731   }
732 
733   return EFI_SUCCESS;
734 }
735 
736 EFI_STATUS
DmaBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,IN OUT VOID * Buffer,IN UINTN BlockCount,IN OPERATION_TYPE OperationType)737 DmaBlocks (
738   IN EFI_BLOCK_IO_PROTOCOL        *This,
739   IN  UINTN                       Lba,
740   IN OUT VOID                     *Buffer,
741   IN  UINTN                       BlockCount,
742   IN  OPERATION_TYPE              OperationType
743   )
744 {
745   EFI_STATUS            Status;
746   UINTN                 DmaSize = 0;
747   UINTN                 Cmd = 0;
748   UINTN                 CmdInterruptEnable;
749   UINTN                 CmdArgument;
750   VOID                  *BufferMap;
751   EFI_PHYSICAL_ADDRESS  BufferAddress;
752   OMAP_DMA4             Dma4;
753   DMA_MAP_OPERATION     DmaOperation;
754   EFI_STATUS            MmcStatus;
755   UINTN                 RetryCount = 0;
756 
757 CpuDeadLoop ();
758   // Map passed in buffer for DMA xfer
759   DmaSize = BlockCount * This->Media->BlockSize;
760   Status = DmaMap (DmaOperation, Buffer, &DmaSize, &BufferAddress, &BufferMap);
761   if (EFI_ERROR (Status)) {
762     return Status;
763   }
764 
765   ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION));
766 
767 
768   Dma4.DataType = 2;                      // DMA4_CSDPi[1:0]   32-bit elements from MMCHS_DATA
769 
770   Dma4.SourceEndiansim = 0;               // DMA4_CSDPi[21]
771 
772   Dma4.DestinationEndianism = 0;          // DMA4_CSDPi[19]
773 
774   Dma4.SourcePacked = 0;                  // DMA4_CSDPi[6]
775 
776   Dma4.DestinationPacked = 0;             // DMA4_CSDPi[13]
777 
778   Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi  (TRM 4K is optimum value)
779 
780   Dma4.NumberOfFramePerTransferBlock = BlockCount;         // DMA4_CFNi
781 
782   Dma4.ReadPriority = 0;                  // DMA4_CCRi[6]      Low priority read
783 
784   Dma4.WritePriority = 0;                 // DMA4_CCRi[23]     Prefetech disabled
785 
786 
787   //Populate the command information based on the operation type.
788   if (OperationType == READ) {
789     Cmd = CMD18; //Multiple block read
790     CmdInterruptEnable = CMD18_INT_EN;
791     DmaOperation = MapOperationBusMasterCommonBuffer;
792 
793     Dma4.ReadPortAccessType =0 ;            // DMA4_CSDPi[8:7]   Can not burst MMCHS_DATA reg
794 
795     Dma4.WritePortAccessType = 3;           // DMA4_CSDPi[15:14] Memory burst 16x32
796 
797     Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted
798 
799 
800 
801     Dma4.SourceStartAddress = MMCHS_DATA;                   // DMA4_CSSAi
802 
803     Dma4.DestinationStartAddress = (UINT32)BufferAddress;   // DMA4_CDSAi
804 
805     Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
806 
807     Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
808 
809     Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
810 
811     Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
812 
813 
814 
815     Dma4.ReadPortAccessMode = 0;            // DMA4_CCRi[13:12]  Always read MMCHS_DATA
816 
817     Dma4.WritePortAccessMode = 1;           // DMA4_CCRi[15:14]  Post increment memory address
818 
819     Dma4.ReadRequestNumber = 0x1e;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_RX (61)
820 
821     Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3e == 62 (one based)
822 
823   } else if (OperationType == WRITE) {
824     Cmd = CMD25; //Multiple block write
825     CmdInterruptEnable = CMD25_INT_EN;
826     DmaOperation = MapOperationBusMasterRead;
827 
828     Dma4.ReadPortAccessType = 3;            // DMA4_CSDPi[8:7]   Memory burst 16x32
829 
830     Dma4.WritePortAccessType = 0;           // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg
831 
832     Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted ???
833 
834 
835 
836     Dma4.SourceStartAddress = (UINT32)BufferAddress;        // DMA4_CSSAi
837 
838     Dma4.DestinationStartAddress = MMCHS_DATA;              // DMA4_CDSAi
839 
840     Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
841 
842     Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
843 
844     Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
845 
846     Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
847 
848 
849 
850     Dma4.ReadPortAccessMode = 1;            // DMA4_CCRi[13:12]  Post increment memory address
851 
852     Dma4.WritePortAccessMode = 0;           // DMA4_CCRi[15:14]  Always write MMCHS_DATA
853 
854     Dma4.ReadRequestNumber = 0x1d;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_TX (60)
855 
856     Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3d == 61 (one based)
857 
858   } else {
859     return EFI_INVALID_PARAMETER;
860   }
861 
862 
863   EnableDmaChannel (2, &Dma4);
864 
865 
866   //Set command argument based on the card access mode (Byte mode or Block mode)
867   if (gCardInfo.OCRData.AccessMode & BIT1) {
868     CmdArgument = Lba;
869   } else {
870     CmdArgument = Lba * This->Media->BlockSize;
871   }
872 
873   //Send Command.
874   Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
875   if (EFI_ERROR (Status)) {
876     DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
877     return Status;
878   }
879 
880     //Check for the Transfer completion.
881   while (RetryCount < MAX_RETRY_COUNT) {
882     //Read Status
883     do {
884       MmcStatus = MmioRead32 (MMCHS_STAT);
885     } while (MmcStatus == 0);
886 
887     //Check if Transfer complete (TC) bit is set?
888     if (MmcStatus & TC) {
889       break;
890     } else {
891       DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
892       //Check if DEB, DCRC or DTO interrupt occured.
893       if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
894         //There was an error during the data transfer.
895 
896         //Set SRD bit to 1 and wait until it return to 0x0.
897         MmioOr32 (MMCHS_SYSCTL, SRD);
898         while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
899 
900         DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
901         DmaUnmap (BufferMap);
902         return EFI_DEVICE_ERROR;
903       }
904     }
905     RetryCount++;
906   }
907 
908   DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
909   Status = DmaUnmap (BufferMap);
910 
911   if (RetryCount == MAX_RETRY_COUNT) {
912     DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
913     return EFI_TIMEOUT;
914   }
915 
916   return Status;
917 }
918 
919 
920 EFI_STATUS
TransferBlock(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,IN OUT VOID * Buffer,IN OPERATION_TYPE OperationType)921 TransferBlock (
922   IN EFI_BLOCK_IO_PROTOCOL        *This,
923   IN  UINTN                       Lba,
924   IN OUT VOID                     *Buffer,
925   IN  OPERATION_TYPE              OperationType
926   )
927 {
928   EFI_STATUS Status;
929   UINTN      MmcStatus;
930   UINTN      RetryCount = 0;
931   UINTN      Cmd = 0;
932   UINTN      CmdInterruptEnable = 0;
933   UINTN      CmdArgument = 0;
934 
935 
936   //Populate the command information based on the operation type.
937   if (OperationType == READ) {
938     Cmd = CMD17; //Single block read
939     CmdInterruptEnable = CMD18_INT_EN;
940   } else if (OperationType == WRITE) {
941     Cmd = CMD24; //Single block write
942     CmdInterruptEnable = CMD24_INT_EN;
943   }
944 
945   //Set command argument based on the card access mode (Byte mode or Block mode)
946   if (gCardInfo.OCRData.AccessMode & BIT1) {
947     CmdArgument = Lba;
948   } else {
949     CmdArgument = Lba * This->Media->BlockSize;
950   }
951 
952   //Send Command.
953   Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
954   if (EFI_ERROR(Status)) {
955     DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
956     return Status;
957   }
958 
959   //Read or Write data.
960   if (OperationType == READ) {
961     Status = ReadBlockData (This, Buffer);
962     if (EFI_ERROR(Status)) {
963       DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
964       return Status;
965     }
966   } else if (OperationType == WRITE) {
967     Status = WriteBlockData (This, Buffer);
968     if (EFI_ERROR(Status)) {
969       DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
970       return Status;
971     }
972   }
973 
974   //Check for the Transfer completion.
975   while (RetryCount < MAX_RETRY_COUNT) {
976     //Read Status
977     do {
978       MmcStatus = MmioRead32 (MMCHS_STAT);
979     } while (MmcStatus == 0);
980 
981     //Check if Transfer complete (TC) bit is set?
982     if (MmcStatus & TC) {
983       break;
984     } else {
985       DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
986       //Check if DEB, DCRC or DTO interrupt occured.
987       if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
988         //There was an error during the data transfer.
989 
990         //Set SRD bit to 1 and wait until it return to 0x0.
991         MmioOr32 (MMCHS_SYSCTL, SRD);
992         while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
993 
994         return EFI_DEVICE_ERROR;
995       }
996     }
997     RetryCount++;
998   }
999 
1000   if (RetryCount == MAX_RETRY_COUNT) {
1001     DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
1002     return EFI_TIMEOUT;
1003   }
1004 
1005   return EFI_SUCCESS;
1006 }
1007 
1008 BOOLEAN
CardPresent(VOID)1009 CardPresent (
1010   VOID
1011   )
1012 {
1013   EFI_STATUS  Status;
1014   UINT8       Data;
1015 
1016   //
1017   // Card detect is a GPIO0 on the TPS65950
1018   //
1019   Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
1020   if (EFI_ERROR (Status)) {
1021     return FALSE;
1022   }
1023 
1024   if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
1025     // No Card present
1026     return FALSE;
1027   } else {
1028     return TRUE;
1029   }
1030 }
1031 
1032 EFI_STATUS
DetectCard(VOID)1033 DetectCard (
1034   VOID
1035   )
1036 {
1037   EFI_STATUS    Status;
1038 
1039   if (!CardPresent ()) {
1040     return EFI_NO_MEDIA;
1041   }
1042 
1043   //Initialize MMC host controller clocks.
1044   Status = InitializeMMCHS ();
1045   if (EFI_ERROR(Status)) {
1046     DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
1047     return Status;
1048   }
1049 
1050   //Software reset of the MMCHS host controller.
1051   MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
1052   gBS->Stall(1000);
1053   while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
1054 
1055   //Soft reset for all.
1056   MmioWrite32 (MMCHS_SYSCTL, SRA);
1057   gBS->Stall(1000);
1058   while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
1059 
1060   //Voltage capabilities initialization. Activate VS18 and VS30.
1061   MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
1062 
1063   //Wakeup configuration
1064   MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
1065   MmioOr32 (MMCHS_HCTL, IWE);
1066 
1067   //MMCHS Controller default initialization
1068   MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
1069 
1070   MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
1071 
1072   //Enable internal clock
1073   MmioOr32 (MMCHS_SYSCTL, ICE);
1074 
1075   //Set the clock frequency to 80KHz.
1076   UpdateMMCHSClkFrequency (CLKD_80KHZ);
1077 
1078   //Enable SD bus power.
1079   MmioOr32 (MMCHS_HCTL, (SDBP_ON));
1080 
1081   //Poll till SD bus power bit is set.
1082   while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
1083 
1084   //Card idenfication
1085   Status = PerformCardIdenfication ();
1086   if (EFI_ERROR(Status)) {
1087     DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
1088     return Status;
1089   }
1090 
1091   //Get CSD (Card specific data) for the detected card.
1092   Status = GetCardSpecificData();
1093   if (EFI_ERROR(Status)) {
1094     return Status;
1095   }
1096 
1097   //Configure the card in data transfer mode.
1098   Status = PerformCardConfiguration();
1099   if (EFI_ERROR(Status)) {
1100     return Status;
1101   }
1102 
1103   //Patch the Media structure.
1104   gMMCHSMedia.LastBlock    = (gCardInfo.NumBlocks - 1);
1105   gMMCHSMedia.BlockSize    = gCardInfo.BlockSize;
1106   gMMCHSMedia.ReadOnly     = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
1107   gMMCHSMedia.MediaPresent = TRUE;
1108   gMMCHSMedia.MediaId++;
1109 
1110   DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
1111 
1112   return Status;
1113 }
1114 
1115 #define MAX_MMCHS_TRANSFER_SIZE  0x4000
1116 
1117 EFI_STATUS
SdReadWrite(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,OUT VOID * Buffer,IN UINTN BufferSize,IN OPERATION_TYPE OperationType)1118 SdReadWrite (
1119   IN EFI_BLOCK_IO_PROTOCOL    *This,
1120   IN  UINTN                   Lba,
1121   OUT VOID                    *Buffer,
1122   IN  UINTN                   BufferSize,
1123   IN  OPERATION_TYPE          OperationType
1124   )
1125 {
1126   EFI_STATUS Status = EFI_SUCCESS;
1127   UINTN      RetryCount = 0;
1128   UINTN      BlockCount;
1129   UINTN      BytesToBeTranferedThisPass = 0;
1130   UINTN      BytesRemainingToBeTransfered;
1131   EFI_TPL    OldTpl;
1132 
1133   BOOLEAN    Update;
1134 
1135 
1136 
1137   Update               = FALSE;
1138 
1139   if (gMediaChange) {
1140     Update = TRUE;
1141     Status = DetectCard  ();
1142     if (EFI_ERROR (Status)) {
1143       // We detected a removal
1144       gMMCHSMedia.MediaPresent = FALSE;
1145       gMMCHSMedia.LastBlock    = 0;
1146       gMMCHSMedia.BlockSize    = 512;  // Should be zero but there is a bug in DiskIo
1147       gMMCHSMedia.ReadOnly     = FALSE;
1148     }
1149     gMediaChange             = FALSE;
1150   } else if (!gMMCHSMedia.MediaPresent) {
1151     Status = EFI_NO_MEDIA;
1152     goto Done;
1153   }
1154 
1155   if (Update) {
1156     DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
1157     gBS->ReinstallProtocolInterface (
1158           gImageHandle,
1159           &gEfiBlockIoProtocolGuid,
1160           &gBlockIo,
1161           &gBlockIo
1162           );
1163     return EFI_MEDIA_CHANGED;
1164   }
1165 
1166   if (EFI_ERROR (Status)) {
1167     goto Done;
1168   }
1169 
1170   if (Buffer == NULL) {
1171     Status = EFI_INVALID_PARAMETER;
1172     goto Done;
1173   }
1174 
1175   if (Lba > This->Media->LastBlock) {
1176     Status = EFI_INVALID_PARAMETER;
1177     goto Done;
1178   }
1179 
1180   if ((BufferSize % This->Media->BlockSize) != 0) {
1181     Status = EFI_BAD_BUFFER_SIZE;
1182     goto Done;
1183   }
1184 
1185   //Check if the data lines are not in use.
1186   while ((RetryCount++ < MAX_RETRY_COUNT) && ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) != DATI_ALLOWED));
1187   if (RetryCount == MAX_RETRY_COUNT) {
1188     Status = EFI_TIMEOUT;
1189     goto Done;
1190   }
1191 
1192   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1193 
1194   BytesRemainingToBeTransfered = BufferSize;
1195   while (BytesRemainingToBeTransfered > 0) {
1196 
1197     if (gMediaChange) {
1198       Status = EFI_NO_MEDIA;
1199       DEBUG ((EFI_D_INFO, "SdReadWrite() EFI_NO_MEDIA due to gMediaChange\n"));
1200       goto DoneRestoreTPL;
1201     }
1202 
1203     // Turn OFF DMA path until it is debugged
1204     // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
1205     BytesToBeTranferedThisPass   = This->Media->BlockSize;
1206 
1207     BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
1208 
1209     if (BlockCount > 1) {
1210       Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
1211     } else {
1212       //Transfer a block worth of data.
1213       Status = TransferBlock (This, Lba, Buffer, OperationType);
1214     }
1215 
1216     if (EFI_ERROR(Status)) {
1217       DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
1218       goto DoneRestoreTPL;
1219     }
1220 
1221     BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
1222     Lba    += BlockCount;
1223     Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
1224   }
1225 
1226 DoneRestoreTPL:
1227 
1228   gBS->RestoreTPL (OldTpl);
1229 
1230 Done:
1231 
1232   return Status;
1233 
1234 }
1235 
1236 
1237 /**
1238 
1239   Reset the Block Device.
1240 
1241 
1242 
1243   @param  This                 Indicates a pointer to the calling context.
1244 
1245   @param  ExtendedVerification Driver may perform diagnostics on reset.
1246 
1247 
1248 
1249   @retval EFI_SUCCESS          The device was reset.
1250 
1251   @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
1252 
1253                                not be reset.
1254 
1255 
1256 
1257 **/
1258 EFI_STATUS
1259 EFIAPI
MMCHSReset(IN EFI_BLOCK_IO_PROTOCOL * This,IN BOOLEAN ExtendedVerification)1260 MMCHSReset (
1261   IN EFI_BLOCK_IO_PROTOCOL          *This,
1262   IN BOOLEAN                        ExtendedVerification
1263   )
1264 {
1265   return EFI_SUCCESS;
1266 }
1267 
1268 
1269 /**
1270 
1271   Read BufferSize bytes from Lba into Buffer.
1272 
1273 
1274 
1275   @param  This       Indicates a pointer to the calling context.
1276 
1277   @param  MediaId    Id of the media, changes every time the media is replaced.
1278 
1279   @param  Lba        The starting Logical Block Address to read from
1280 
1281   @param  BufferSize Size of Buffer, must be a multiple of device block size.
1282 
1283   @param  Buffer     A pointer to the destination buffer for the data. The caller is
1284 
1285                      responsible for either having implicit or explicit ownership of the buffer.
1286 
1287 
1288 
1289   @retval EFI_SUCCESS           The data was read correctly from the device.
1290 
1291   @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
1292 
1293   @retval EFI_NO_MEDIA          There is no media in the device.
1294 
1295   @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
1296 
1297   @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
1298 
1299   @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1300 
1301                                 or the buffer is not on proper alignment.
1302 
1303 EFI_STATUS
1304 
1305 **/
1306 EFI_STATUS
1307 EFIAPI
MMCHSReadBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,OUT VOID * Buffer)1308 MMCHSReadBlocks (
1309   IN EFI_BLOCK_IO_PROTOCOL          *This,
1310   IN UINT32                         MediaId,
1311   IN EFI_LBA                        Lba,
1312   IN UINTN                          BufferSize,
1313   OUT VOID                          *Buffer
1314   )
1315 {
1316   EFI_STATUS Status;
1317 
1318   //Perform Read operation.
1319   Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
1320 
1321   return Status;
1322 
1323 }
1324 
1325 
1326 /**
1327 
1328   Write BufferSize bytes from Lba into Buffer.
1329 
1330 
1331 
1332   @param  This       Indicates a pointer to the calling context.
1333 
1334   @param  MediaId    The media ID that the write request is for.
1335 
1336   @param  Lba        The starting logical block address to be written. The caller is
1337 
1338                      responsible for writing to only legitimate locations.
1339 
1340   @param  BufferSize Size of Buffer, must be a multiple of device block size.
1341 
1342   @param  Buffer     A pointer to the source buffer for the data.
1343 
1344 
1345 
1346   @retval EFI_SUCCESS           The data was written correctly to the device.
1347 
1348   @retval EFI_WRITE_PROTECTED   The device can not be written to.
1349 
1350   @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
1351 
1352   @retval EFI_NO_MEDIA          There is no media in the device.
1353 
1354   @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
1355 
1356   @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
1357 
1358   @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1359 
1360                                 or the buffer is not on proper alignment.
1361 
1362 
1363 
1364 **/
1365 EFI_STATUS
1366 EFIAPI
MMCHSWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,IN VOID * Buffer)1367 MMCHSWriteBlocks (
1368   IN EFI_BLOCK_IO_PROTOCOL          *This,
1369   IN UINT32                         MediaId,
1370   IN EFI_LBA                        Lba,
1371   IN UINTN                          BufferSize,
1372   IN VOID                           *Buffer
1373   )
1374 {
1375   EFI_STATUS  Status;
1376 
1377   //Perform write operation.
1378   Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
1379 
1380 
1381   return Status;
1382 
1383 }
1384 
1385 
1386 /**
1387 
1388   Flush the Block Device.
1389 
1390 
1391 
1392   @param  This              Indicates a pointer to the calling context.
1393 
1394 
1395 
1396   @retval EFI_SUCCESS       All outstanding data was written to the device
1397 
1398   @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
1399 
1400   @retval EFI_NO_MEDIA      There is no media in the device.
1401 
1402 
1403 
1404 **/
1405 EFI_STATUS
1406 EFIAPI
MMCHSFlushBlocks(IN EFI_BLOCK_IO_PROTOCOL * This)1407 MMCHSFlushBlocks (
1408   IN EFI_BLOCK_IO_PROTOCOL  *This
1409   )
1410 {
1411   return EFI_SUCCESS;
1412 }
1413 
1414 
1415 EFI_BLOCK_IO_PROTOCOL gBlockIo = {
1416   EFI_BLOCK_IO_INTERFACE_REVISION,   // Revision
1417   &gMMCHSMedia,                      // *Media
1418   MMCHSReset,                        // Reset
1419   MMCHSReadBlocks,                   // ReadBlocks
1420   MMCHSWriteBlocks,                  // WriteBlocks
1421   MMCHSFlushBlocks                   // FlushBlocks
1422 };
1423 
1424 
1425 /**
1426 
1427   Timer callback to convert card present hardware into a boolean that indicates
1428 
1429   a media change event has happened. If you just check the GPIO you could see
1430 
1431   card 1 and then check again after card 1 was removed and card 2 was inserted
1432 
1433   and you would still see media present. Thus you need the timer tick to catch
1434 
1435   the toggle event.
1436 
1437 
1438 
1439   @param  Event                 Event whose notification function is being invoked.
1440 
1441   @param  Context               The pointer to the notification function's context,
1442 
1443                                 which is implementation-dependent. Not used.
1444 
1445 
1446 
1447 **/
1448 VOID
1449 EFIAPI
TimerCallback(IN EFI_EVENT Event,IN VOID * Context)1450 TimerCallback (
1451   IN  EFI_EVENT   Event,
1452   IN  VOID        *Context
1453   )
1454 {
1455   BOOLEAN Present;
1456 
1457   Present = CardPresent ();
1458   if (gMMCHSMedia.MediaPresent) {
1459     if (!Present && !gMediaChange) {
1460       gMediaChange = TRUE;
1461     }
1462   } else {
1463     if (Present && !gMediaChange) {
1464       gMediaChange = TRUE;
1465     }
1466   }
1467 }
1468 
1469 
1470 EFI_STATUS
1471 EFIAPI
MMCHSInitialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1472 MMCHSInitialize (
1473   IN EFI_HANDLE         ImageHandle,
1474   IN EFI_SYSTEM_TABLE   *SystemTable
1475   )
1476 {
1477   EFI_STATUS  Status;
1478 
1479   Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
1480   ASSERT_EFI_ERROR(Status);
1481 
1482   ZeroMem (&gCardInfo, sizeof (CARD_INFO));
1483 
1484   Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
1485   ASSERT_EFI_ERROR (Status);
1486 
1487   Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, FixedPcdGet32 (PcdMmchsTimerFreq100NanoSeconds));
1488   ASSERT_EFI_ERROR (Status);
1489 
1490   //Publish BlockIO.
1491   Status = gBS->InstallMultipleProtocolInterfaces (
1492                   &ImageHandle,
1493                   &gEfiBlockIoProtocolGuid,    &gBlockIo,
1494                   &gEfiDevicePathProtocolGuid, &gMmcHsDevicePath,
1495                   NULL
1496                   );
1497   return Status;
1498 }
1499