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     HARDWARE_DEVICE_PATH,
47     HW_VENDOR_DP,
48     (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
49     (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
50     0xb615f1f5, 0x5088, 0x43cd, 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00
51   },
52   {
53     END_DEVICE_PATH_TYPE,
54     END_ENTIRE_DEVICE_PATH_SUBTYPE,
55     { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
56   }
57 };
58 
59 CARD_INFO                  gCardInfo;
60 EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
61 EFI_EVENT                  gTimerEvent;
62 BOOLEAN                    gMediaChange = FALSE;
63 
64 //
65 // Internal Functions
66 //
67 
68 
69 VOID
ParseCardCIDData(UINT32 Response0,UINT32 Response1,UINT32 Response2,UINT32 Response3)70 ParseCardCIDData (
71   UINT32 Response0,
72   UINT32 Response1,
73   UINT32 Response2,
74   UINT32 Response3
75   )
76 {
77   gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
78   gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
79   gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
80   gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
81   gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
82   gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
83   gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
84   gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
85   gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
86   gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
87 }
88 
89 
90 VOID
UpdateMMCHSClkFrequency(UINTN NewCLKD)91 UpdateMMCHSClkFrequency (
92   UINTN NewCLKD
93   )
94 {
95   //Set Clock enable to 0x0 to not provide the clock to the card
96   MmioAnd32 (MMCHS_SYSCTL, ~CEN);
97 
98   //Set new clock frequency.
99   MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
100 
101   //Poll till Internal Clock Stable
102   while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
103 
104   //Set Clock enable to 0x1 to provide the clock to the card
105   MmioOr32 (MMCHS_SYSCTL, CEN);
106 }
107 
108 
109 EFI_STATUS
SendCmd(UINTN Cmd,UINTN CmdInterruptEnableVal,UINTN CmdArgument)110 SendCmd (
111   UINTN Cmd,
112   UINTN CmdInterruptEnableVal,
113   UINTN CmdArgument
114   )
115 {
116   UINTN MmcStatus;
117   UINTN RetryCount = 0;
118 
119   //Check if command line is in use or not. Poll till command line is available.
120   while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
121 
122   //Provide the block size.
123   MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
124 
125   //Setting Data timeout counter value to max value.
126   MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
127 
128   //Clear Status register.
129   MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
130 
131   //Set command argument register
132   MmioWrite32 (MMCHS_ARG, CmdArgument);
133 
134   //Enable interrupt enable events to occur
135   MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
136 
137   //Send a command
138   MmioWrite32 (MMCHS_CMD, Cmd);
139 
140   //Check for the command status.
141   while (RetryCount < MAX_RETRY_COUNT) {
142     do {
143       MmcStatus = MmioRead32 (MMCHS_STAT);
144     } while (MmcStatus == 0);
145 
146     //Read status of command response
147     if ((MmcStatus & ERRI) != 0) {
148 
149       //Perform soft-reset for mmci_cmd line.
150       MmioOr32 (MMCHS_SYSCTL, SRC);
151       while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
152 
153       DEBUG ((EFI_D_INFO, "MmcStatus: %x\n", MmcStatus));
154       return EFI_DEVICE_ERROR;
155     }
156 
157     //Check if command is completed.
158     if ((MmcStatus & CC) == CC) {
159       MmioWrite32 (MMCHS_STAT, CC);
160       break;
161     }
162 
163     RetryCount++;
164   }
165 
166   if (RetryCount == MAX_RETRY_COUNT) {
167     return EFI_TIMEOUT;
168   }
169 
170   return EFI_SUCCESS;
171 }
172 
173 
174 VOID
GetBlockInformation(UINTN * BlockSize,UINTN * NumBlocks)175 GetBlockInformation (
176   UINTN *BlockSize,
177   UINTN *NumBlocks
178   )
179 {
180   CSD_SDV2 *CsdSDV2Data;
181   UINTN    CardSize;
182 
183   if (gCardInfo.CardType == SD_CARD_2_HIGH) {
184     CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
185 
186     //Populate BlockSize.
187     *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
188 
189     //Calculate Total number of blocks.
190     CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
191     *NumBlocks = ((CardSize + 1) * 1024);
192   } else {
193     //Populate BlockSize.
194     *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
195 
196     //Calculate Total number of blocks.
197     CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
198     *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
199   }
200 
201   //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
202   if (*BlockSize > 512) {
203     *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
204     *BlockSize = 512;
205   }
206 
207   DEBUG ((EFI_D_INFO, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
208 }
209 
210 
211 VOID
CalculateCardCLKD(UINTN * ClockFrequencySelect)212 CalculateCardCLKD (
213   UINTN *ClockFrequencySelect
214   )
215 {
216   UINT8    MaxDataTransferRate;
217   UINTN    TransferRateValue = 0;
218   UINTN    TimeValue = 0 ;
219   UINTN    Frequency = 0;
220 
221   MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
222 
223   // For SD Cards  we would need to send CMD6 to set
224   // speeds abouve 25MHz. High Speed mode 50 MHz and up
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
GetCardConfigurationData(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
InitializeMMCHS(VOID)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
PerformCardIdenfication(VOID)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
GetCardSpecificData(VOID)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   return Status;
597 }
598 
599 
600 EFI_STATUS
PerformCardConfiguration(VOID)601 PerformCardConfiguration (
602   VOID
603   )
604 {
605   UINTN      CmdArgument = 0;
606   EFI_STATUS Status;
607 
608   //Send CMD7
609   CmdArgument = gCardInfo.RCA << 16;
610   Status = SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
611   if (EFI_ERROR(Status)) {
612     DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
613     return Status;
614   }
615 
616   if ((gCardInfo.CardType != UNKNOWN_CARD) && (gCardInfo.CardType != MMC_CARD)) {
617     // We could read SCR register, but SD Card Phys spec stats any SD Card shall
618     // set SCR.SD_BUS_WIDTHS to support 4-bit mode, so why bother?
619 
620     // Send ACMD6 (application specific commands must be prefixed with CMD55)
621     Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
622     if (!EFI_ERROR (Status)) {
623       // set device into 4-bit data bus mode
624       Status = SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
625       if (!EFI_ERROR (Status)) {
626         // Set host controler into 4-bit mode
627         MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
628         DEBUG ((EFI_D_INFO, "SD Memory Card set to 4-bit mode\n"));
629       }
630     }
631   }
632 
633   //Send CMD16 to set the block length
634   CmdArgument = gCardInfo.BlockSize;
635   Status = SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
636   if (EFI_ERROR(Status)) {
637     DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
638     return Status;
639   }
640 
641   //Change MMCHS clock frequency to what detected card can support.
642   UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
643 
644   return EFI_SUCCESS;
645 }
646 
647 
648 EFI_STATUS
ReadBlockData(IN EFI_BLOCK_IO_PROTOCOL * This,OUT VOID * Buffer)649 ReadBlockData (
650   IN  EFI_BLOCK_IO_PROTOCOL       *This,
651   OUT VOID                        *Buffer
652   )
653 {
654   UINTN MmcStatus;
655   UINTN *DataBuffer = Buffer;
656   UINTN DataSize = This->Media->BlockSize/4;
657   UINTN Count;
658   UINTN RetryCount = 0;
659 
660   //Check controller status to make sure there is no error.
661   while (RetryCount < MAX_RETRY_COUNT) {
662     do {
663       //Read Status.
664       MmcStatus = MmioRead32 (MMCHS_STAT);
665     } while(MmcStatus == 0);
666 
667     //Check if Buffer read ready (BRR) bit is set?
668     if (MmcStatus & BRR) {
669 
670       //Clear BRR bit
671       MmioOr32 (MMCHS_STAT, BRR);
672 
673       //Read block worth of data.
674       for (Count = 0; Count < DataSize; Count++) {
675         *DataBuffer++ = MmioRead32 (MMCHS_DATA);
676       }
677       break;
678     }
679     RetryCount++;
680   }
681 
682   if (RetryCount == MAX_RETRY_COUNT) {
683     return EFI_TIMEOUT;
684   }
685 
686   return EFI_SUCCESS;
687 }
688 
689 
690 EFI_STATUS
WriteBlockData(IN EFI_BLOCK_IO_PROTOCOL * This,OUT VOID * Buffer)691 WriteBlockData (
692   IN  EFI_BLOCK_IO_PROTOCOL       *This,
693   OUT VOID                        *Buffer
694   )
695 {
696   UINTN MmcStatus;
697   UINTN *DataBuffer = Buffer;
698   UINTN DataSize = This->Media->BlockSize/4;
699   UINTN Count;
700   UINTN RetryCount = 0;
701 
702   //Check controller status to make sure there is no error.
703   while (RetryCount < MAX_RETRY_COUNT) {
704     do {
705       //Read Status.
706       MmcStatus = MmioRead32 (MMCHS_STAT);
707     } while(MmcStatus == 0);
708 
709     //Check if Buffer write ready (BWR) bit is set?
710     if (MmcStatus & BWR) {
711 
712       //Clear BWR bit
713       MmioOr32 (MMCHS_STAT, BWR);
714 
715       //Write block worth of data.
716       for (Count = 0; Count < DataSize; Count++) {
717         MmioWrite32 (MMCHS_DATA, *DataBuffer++);
718       }
719 
720       break;
721     }
722     RetryCount++;
723   }
724 
725   if (RetryCount == MAX_RETRY_COUNT) {
726     return EFI_TIMEOUT;
727   }
728 
729   return EFI_SUCCESS;
730 }
731 
732 EFI_STATUS
DmaBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,IN OUT VOID * Buffer,IN UINTN BlockCount,IN OPERATION_TYPE OperationType)733 DmaBlocks (
734   IN EFI_BLOCK_IO_PROTOCOL        *This,
735   IN  UINTN                       Lba,
736   IN OUT VOID                     *Buffer,
737   IN  UINTN                       BlockCount,
738   IN  OPERATION_TYPE              OperationType
739   )
740 {
741   EFI_STATUS            Status;
742   UINTN                 DmaSize = 0;
743   UINTN                 Cmd = 0;
744   UINTN                 CmdInterruptEnable;
745   UINTN                 CmdArgument;
746   VOID                  *BufferMap;
747   EFI_PHYSICAL_ADDRESS  BufferAddress;
748   OMAP_DMA4             Dma4;
749   DMA_MAP_OPERATION     DmaOperation;
750   EFI_STATUS            MmcStatus;
751   UINTN                 RetryCount = 0;
752 
753 CpuDeadLoop ();
754   // Map passed in buffer for DMA xfer
755   DmaSize = BlockCount * This->Media->BlockSize;
756   Status = DmaMap (DmaOperation, Buffer, &DmaSize, &BufferAddress, &BufferMap);
757   if (EFI_ERROR (Status)) {
758     return Status;
759   }
760 
761   ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION));
762 
763 
764   Dma4.DataType = 2;                      // DMA4_CSDPi[1:0]   32-bit elements from MMCHS_DATA
765 
766   Dma4.SourceEndiansim = 0;               // DMA4_CSDPi[21]
767 
768   Dma4.DestinationEndianism = 0;          // DMA4_CSDPi[19]
769 
770   Dma4.SourcePacked = 0;                  // DMA4_CSDPi[6]
771 
772   Dma4.DestinationPacked = 0;             // DMA4_CSDPi[13]
773 
774   Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi  (TRM 4K is optimum value)
775 
776   Dma4.NumberOfFramePerTransferBlock = BlockCount;         // DMA4_CFNi
777 
778   Dma4.ReadPriority = 0;                  // DMA4_CCRi[6]      Low priority read
779 
780   Dma4.WritePriority = 0;                 // DMA4_CCRi[23]     Prefetech disabled
781 
782 
783   //Populate the command information based on the operation type.
784   if (OperationType == READ) {
785     Cmd = CMD18; //Multiple block read
786     CmdInterruptEnable = CMD18_INT_EN;
787     DmaOperation = MapOperationBusMasterCommonBuffer;
788 
789     Dma4.ReadPortAccessType =0 ;            // DMA4_CSDPi[8:7]   Can not burst MMCHS_DATA reg
790 
791     Dma4.WritePortAccessType = 3;           // DMA4_CSDPi[15:14] Memory burst 16x32
792 
793     Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted
794 
795 
796 
797     Dma4.SourceStartAddress = MMCHS_DATA;                   // DMA4_CSSAi
798 
799     Dma4.DestinationStartAddress = (UINT32)BufferAddress;   // DMA4_CDSAi
800 
801     Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
802 
803     Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
804 
805     Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
806 
807     Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
808 
809 
810 
811     Dma4.ReadPortAccessMode = 0;            // DMA4_CCRi[13:12]  Always read MMCHS_DATA
812 
813     Dma4.WritePortAccessMode = 1;           // DMA4_CCRi[15:14]  Post increment memory address
814 
815     Dma4.ReadRequestNumber = 0x1e;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_RX (61)
816 
817     Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3e == 62 (one based)
818 
819   } else if (OperationType == WRITE) {
820     Cmd = CMD25; //Multiple block write
821     CmdInterruptEnable = CMD25_INT_EN;
822     DmaOperation = MapOperationBusMasterRead;
823 
824     Dma4.ReadPortAccessType = 3;            // DMA4_CSDPi[8:7]   Memory burst 16x32
825 
826     Dma4.WritePortAccessType = 0;           // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg
827 
828     Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted ???
829 
830 
831 
832     Dma4.SourceStartAddress = (UINT32)BufferAddress;        // DMA4_CSSAi
833 
834     Dma4.DestinationStartAddress = MMCHS_DATA;              // DMA4_CDSAi
835 
836     Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
837 
838     Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
839 
840     Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
841 
842     Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
843 
844 
845 
846     Dma4.ReadPortAccessMode = 1;            // DMA4_CCRi[13:12]  Post increment memory address
847 
848     Dma4.WritePortAccessMode = 0;           // DMA4_CCRi[15:14]  Always write MMCHS_DATA
849 
850     Dma4.ReadRequestNumber = 0x1d;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_TX (60)
851 
852     Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3d == 61 (one based)
853 
854   } else {
855     return EFI_INVALID_PARAMETER;
856   }
857 
858 
859   EnableDmaChannel (2, &Dma4);
860 
861 
862   //Set command argument based on the card access mode (Byte mode or Block mode)
863   if (gCardInfo.OCRData.AccessMode & BIT1) {
864     CmdArgument = Lba;
865   } else {
866     CmdArgument = Lba * This->Media->BlockSize;
867   }
868 
869   //Send Command.
870   Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
871   if (EFI_ERROR (Status)) {
872     DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
873     return Status;
874   }
875 
876     //Check for the Transfer completion.
877   while (RetryCount < MAX_RETRY_COUNT) {
878     //Read Status
879     do {
880       MmcStatus = MmioRead32 (MMCHS_STAT);
881     } while (MmcStatus == 0);
882 
883     //Check if Transfer complete (TC) bit is set?
884     if (MmcStatus & TC) {
885       break;
886     } else {
887       DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
888       //Check if DEB, DCRC or DTO interrupt occured.
889       if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
890         //There was an error during the data transfer.
891 
892         //Set SRD bit to 1 and wait until it return to 0x0.
893         MmioOr32 (MMCHS_SYSCTL, SRD);
894         while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
895 
896         DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
897         DmaUnmap (BufferMap);
898         return EFI_DEVICE_ERROR;
899       }
900     }
901     RetryCount++;
902   }
903 
904   DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
905   Status = DmaUnmap (BufferMap);
906 
907   if (RetryCount == MAX_RETRY_COUNT) {
908     DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
909     return EFI_TIMEOUT;
910   }
911 
912   return Status;
913 }
914 
915 
916 EFI_STATUS
TransferBlock(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,IN OUT VOID * Buffer,IN OPERATION_TYPE OperationType)917 TransferBlock (
918   IN EFI_BLOCK_IO_PROTOCOL        *This,
919   IN  UINTN                       Lba,
920   IN OUT VOID                     *Buffer,
921   IN  OPERATION_TYPE              OperationType
922   )
923 {
924   EFI_STATUS Status;
925   UINTN      MmcStatus;
926   UINTN      RetryCount = 0;
927   UINTN      Cmd = 0;
928   UINTN      CmdInterruptEnable = 0;
929   UINTN      CmdArgument = 0;
930 
931 
932   //Populate the command information based on the operation type.
933   if (OperationType == READ) {
934     Cmd = CMD17; //Single block read
935     CmdInterruptEnable = CMD18_INT_EN;
936   } else if (OperationType == WRITE) {
937     Cmd = CMD24; //Single block write
938     CmdInterruptEnable = CMD24_INT_EN;
939   }
940 
941   //Set command argument based on the card access mode (Byte mode or Block mode)
942   if (gCardInfo.OCRData.AccessMode & BIT1) {
943     CmdArgument = Lba;
944   } else {
945     CmdArgument = Lba * This->Media->BlockSize;
946   }
947 
948   //Send Command.
949   Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
950   if (EFI_ERROR(Status)) {
951     DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
952     return Status;
953   }
954 
955   //Read or Write data.
956   if (OperationType == READ) {
957     Status = ReadBlockData (This, Buffer);
958     if (EFI_ERROR(Status)) {
959       DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
960       return Status;
961     }
962   } else if (OperationType == WRITE) {
963     Status = WriteBlockData (This, Buffer);
964     if (EFI_ERROR(Status)) {
965       DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
966       return Status;
967     }
968   }
969 
970   //Check for the Transfer completion.
971   while (RetryCount < MAX_RETRY_COUNT) {
972     //Read Status
973     do {
974       MmcStatus = MmioRead32 (MMCHS_STAT);
975     } while (MmcStatus == 0);
976 
977     //Check if Transfer complete (TC) bit is set?
978     if (MmcStatus & TC) {
979       break;
980     } else {
981       DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
982       //Check if DEB, DCRC or DTO interrupt occured.
983       if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
984         //There was an error during the data transfer.
985 
986         //Set SRD bit to 1 and wait until it return to 0x0.
987         MmioOr32 (MMCHS_SYSCTL, SRD);
988         while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
989 
990         return EFI_DEVICE_ERROR;
991       }
992     }
993     RetryCount++;
994   }
995 
996   if (RetryCount == MAX_RETRY_COUNT) {
997     DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
998     return EFI_TIMEOUT;
999   }
1000 
1001   return EFI_SUCCESS;
1002 }
1003 
1004 BOOLEAN
CardPresent(VOID)1005 CardPresent (
1006   VOID
1007   )
1008 {
1009   EFI_STATUS  Status;
1010   UINT8       Data;
1011 
1012   //
1013   // Card detect is a GPIO0 on the TPS65950
1014   //
1015   Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
1016   if (EFI_ERROR (Status)) {
1017     return FALSE;
1018   }
1019 
1020   if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
1021     // No Card present
1022     return FALSE;
1023   } else {
1024     return TRUE;
1025   }
1026 }
1027 
1028 EFI_STATUS
DetectCard(VOID)1029 DetectCard (
1030   VOID
1031   )
1032 {
1033   EFI_STATUS    Status;
1034 
1035   if (!CardPresent ()) {
1036     return EFI_NO_MEDIA;
1037   }
1038 
1039   //Initialize MMC host controller clocks.
1040   Status = InitializeMMCHS ();
1041   if (EFI_ERROR(Status)) {
1042     DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
1043     return Status;
1044   }
1045 
1046   //Software reset of the MMCHS host controller.
1047   MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
1048   gBS->Stall(1000);
1049   while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
1050 
1051   //Soft reset for all.
1052   MmioWrite32 (MMCHS_SYSCTL, SRA);
1053   gBS->Stall(1000);
1054   while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
1055 
1056   //Voltage capabilities initialization. Activate VS18 and VS30.
1057   MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
1058 
1059   //Wakeup configuration
1060   MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
1061   MmioOr32 (MMCHS_HCTL, IWE);
1062 
1063   //MMCHS Controller default initialization
1064   MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
1065 
1066   MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
1067 
1068   //Enable internal clock
1069   MmioOr32 (MMCHS_SYSCTL, ICE);
1070 
1071   //Set the clock frequency to 80KHz.
1072   UpdateMMCHSClkFrequency (CLKD_80KHZ);
1073 
1074   //Enable SD bus power.
1075   MmioOr32 (MMCHS_HCTL, (SDBP_ON));
1076 
1077   //Poll till SD bus power bit is set.
1078   while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
1079 
1080   //Card idenfication
1081   Status = PerformCardIdenfication ();
1082   if (EFI_ERROR(Status)) {
1083     DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
1084     return Status;
1085   }
1086 
1087   //Get CSD (Card specific data) for the detected card.
1088   Status = GetCardSpecificData();
1089   if (EFI_ERROR(Status)) {
1090     return Status;
1091   }
1092 
1093   //Configure the card in data transfer mode.
1094   Status = PerformCardConfiguration();
1095   if (EFI_ERROR(Status)) {
1096     return Status;
1097   }
1098 
1099   //Patch the Media structure.
1100   gMMCHSMedia.LastBlock    = (gCardInfo.NumBlocks - 1);
1101   gMMCHSMedia.BlockSize    = gCardInfo.BlockSize;
1102   gMMCHSMedia.ReadOnly     = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
1103   gMMCHSMedia.MediaPresent = TRUE;
1104   gMMCHSMedia.MediaId++;
1105 
1106   DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
1107 
1108   return Status;
1109 }
1110 
1111 #define MAX_MMCHS_TRANSFER_SIZE  0x4000
1112 
1113 EFI_STATUS
SdReadWrite(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINTN Lba,OUT VOID * Buffer,IN UINTN BufferSize,IN OPERATION_TYPE OperationType)1114 SdReadWrite (
1115   IN EFI_BLOCK_IO_PROTOCOL    *This,
1116   IN  UINTN                   Lba,
1117   OUT VOID                    *Buffer,
1118   IN  UINTN                   BufferSize,
1119   IN  OPERATION_TYPE          OperationType
1120   )
1121 {
1122   EFI_STATUS Status = EFI_SUCCESS;
1123   UINTN      RetryCount = 0;
1124   UINTN      BlockCount;
1125   UINTN      BytesToBeTranferedThisPass = 0;
1126   UINTN      BytesRemainingToBeTransfered;
1127   EFI_TPL    OldTpl;
1128 
1129   BOOLEAN    Update;
1130 
1131 
1132 
1133   Update               = FALSE;
1134 
1135   if (gMediaChange) {
1136     Update = TRUE;
1137     Status = DetectCard  ();
1138     if (EFI_ERROR (Status)) {
1139       // We detected a removal
1140       gMMCHSMedia.MediaPresent = FALSE;
1141       gMMCHSMedia.LastBlock    = 0;
1142       gMMCHSMedia.BlockSize    = 512;  // Should be zero but there is a bug in DiskIo
1143       gMMCHSMedia.ReadOnly     = FALSE;
1144     }
1145     gMediaChange             = FALSE;
1146   } else if (!gMMCHSMedia.MediaPresent) {
1147     Status = EFI_NO_MEDIA;
1148     goto Done;
1149   }
1150 
1151   if (Update) {
1152     DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
1153     gBS->ReinstallProtocolInterface (
1154           gImageHandle,
1155           &gEfiBlockIoProtocolGuid,
1156           &gBlockIo,
1157           &gBlockIo
1158           );
1159     return EFI_MEDIA_CHANGED;
1160   }
1161 
1162   if (EFI_ERROR (Status)) {
1163     goto Done;
1164   }
1165 
1166   if (Buffer == NULL) {
1167     Status = EFI_INVALID_PARAMETER;
1168     goto Done;
1169   }
1170 
1171   if (Lba > This->Media->LastBlock) {
1172     Status = EFI_INVALID_PARAMETER;
1173     goto Done;
1174   }
1175 
1176   if ((BufferSize % This->Media->BlockSize) != 0) {
1177     Status = EFI_BAD_BUFFER_SIZE;
1178     goto Done;
1179   }
1180 
1181   //Check if the data lines are not in use.
1182   while ((RetryCount++ < MAX_RETRY_COUNT) && ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) != DATI_ALLOWED));
1183   if (RetryCount == MAX_RETRY_COUNT) {
1184     Status = EFI_TIMEOUT;
1185     goto Done;
1186   }
1187 
1188   OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1189 
1190   BytesRemainingToBeTransfered = BufferSize;
1191   while (BytesRemainingToBeTransfered > 0) {
1192 
1193     if (gMediaChange) {
1194       Status = EFI_NO_MEDIA;
1195       DEBUG ((EFI_D_INFO, "SdReadWrite() EFI_NO_MEDIA due to gMediaChange\n"));
1196       goto DoneRestoreTPL;
1197     }
1198 
1199     // Turn OFF DMA path until it is debugged
1200     // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
1201     BytesToBeTranferedThisPass   = This->Media->BlockSize;
1202 
1203     BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
1204 
1205     if (BlockCount > 1) {
1206       Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
1207     } else {
1208       //Transfer a block worth of data.
1209       Status = TransferBlock (This, Lba, Buffer, OperationType);
1210     }
1211 
1212     if (EFI_ERROR(Status)) {
1213       DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
1214       goto DoneRestoreTPL;
1215     }
1216 
1217     BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
1218     Lba    += BlockCount;
1219     Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
1220   }
1221 
1222 DoneRestoreTPL:
1223 
1224   gBS->RestoreTPL (OldTpl);
1225 
1226 Done:
1227 
1228   return Status;
1229 
1230 }
1231 
1232 
1233 /**
1234 
1235   Reset the Block Device.
1236 
1237 
1238 
1239   @param  This                 Indicates a pointer to the calling context.
1240 
1241   @param  ExtendedVerification Driver may perform diagnostics on reset.
1242 
1243 
1244 
1245   @retval EFI_SUCCESS          The device was reset.
1246 
1247   @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
1248 
1249                                not be reset.
1250 
1251 
1252 
1253 **/
1254 EFI_STATUS
1255 EFIAPI
MMCHSReset(IN EFI_BLOCK_IO_PROTOCOL * This,IN BOOLEAN ExtendedVerification)1256 MMCHSReset (
1257   IN EFI_BLOCK_IO_PROTOCOL          *This,
1258   IN BOOLEAN                        ExtendedVerification
1259   )
1260 {
1261   return EFI_SUCCESS;
1262 }
1263 
1264 
1265 /**
1266 
1267   Read BufferSize bytes from Lba into Buffer.
1268 
1269 
1270 
1271   @param  This       Indicates a pointer to the calling context.
1272 
1273   @param  MediaId    Id of the media, changes every time the media is replaced.
1274 
1275   @param  Lba        The starting Logical Block Address to read from
1276 
1277   @param  BufferSize Size of Buffer, must be a multiple of device block size.
1278 
1279   @param  Buffer     A pointer to the destination buffer for the data. The caller is
1280 
1281                      responsible for either having implicit or explicit ownership of the buffer.
1282 
1283 
1284 
1285   @retval EFI_SUCCESS           The data was read correctly from the device.
1286 
1287   @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
1288 
1289   @retval EFI_NO_MEDIA          There is no media in the device.
1290 
1291   @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
1292 
1293   @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
1294 
1295   @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
1296 
1297                                 or the buffer is not on proper alignment.
1298 
1299 EFI_STATUS
1300 
1301 **/
1302 EFI_STATUS
1303 EFIAPI
MMCHSReadBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,OUT VOID * Buffer)1304 MMCHSReadBlocks (
1305   IN EFI_BLOCK_IO_PROTOCOL          *This,
1306   IN UINT32                         MediaId,
1307   IN EFI_LBA                        Lba,
1308   IN UINTN                          BufferSize,
1309   OUT VOID                          *Buffer
1310   )
1311 {
1312   EFI_STATUS Status;
1313 
1314   //Perform Read operation.
1315   Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
1316 
1317   return Status;
1318 
1319 }
1320 
1321 
1322 /**
1323 
1324   Write BufferSize bytes from Lba into Buffer.
1325 
1326 
1327 
1328   @param  This       Indicates a pointer to the calling context.
1329 
1330   @param  MediaId    The media ID that the write request is for.
1331 
1332   @param  Lba        The starting logical block address to be written. The caller is
1333 
1334                      responsible for writing to only legitimate locations.
1335 
1336   @param  BufferSize Size of Buffer, must be a multiple of device block size.
1337 
1338   @param  Buffer     A pointer to the source buffer for the data.
1339 
1340 
1341 
1342   @retval EFI_SUCCESS           The data was written correctly to the device.
1343 
1344   @retval EFI_WRITE_PROTECTED   The device can not be written to.
1345 
1346   @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
1347 
1348   @retval EFI_NO_MEDIA          There is no media in the device.
1349 
1350   @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
1351 
1352   @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
1353 
1354   @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
1355 
1356                                 or the buffer is not on proper alignment.
1357 
1358 
1359 
1360 **/
1361 EFI_STATUS
1362 EFIAPI
MMCHSWriteBlocks(IN EFI_BLOCK_IO_PROTOCOL * This,IN UINT32 MediaId,IN EFI_LBA Lba,IN UINTN BufferSize,IN VOID * Buffer)1363 MMCHSWriteBlocks (
1364   IN EFI_BLOCK_IO_PROTOCOL          *This,
1365   IN UINT32                         MediaId,
1366   IN EFI_LBA                        Lba,
1367   IN UINTN                          BufferSize,
1368   IN VOID                           *Buffer
1369   )
1370 {
1371   EFI_STATUS  Status;
1372 
1373   //Perform write operation.
1374   Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
1375 
1376 
1377   return Status;
1378 
1379 }
1380 
1381 
1382 /**
1383 
1384   Flush the Block Device.
1385 
1386 
1387 
1388   @param  This              Indicates a pointer to the calling context.
1389 
1390 
1391 
1392   @retval EFI_SUCCESS       All outstanding data was written to the device
1393 
1394   @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
1395 
1396   @retval EFI_NO_MEDIA      There is no media in the device.
1397 
1398 
1399 
1400 **/
1401 EFI_STATUS
1402 EFIAPI
MMCHSFlushBlocks(IN EFI_BLOCK_IO_PROTOCOL * This)1403 MMCHSFlushBlocks (
1404   IN EFI_BLOCK_IO_PROTOCOL  *This
1405   )
1406 {
1407   return EFI_SUCCESS;
1408 }
1409 
1410 
1411 EFI_BLOCK_IO_PROTOCOL gBlockIo = {
1412   EFI_BLOCK_IO_INTERFACE_REVISION,   // Revision
1413   &gMMCHSMedia,                      // *Media
1414   MMCHSReset,                        // Reset
1415   MMCHSReadBlocks,                   // ReadBlocks
1416   MMCHSWriteBlocks,                  // WriteBlocks
1417   MMCHSFlushBlocks                   // FlushBlocks
1418 };
1419 
1420 
1421 /**
1422 
1423   Timer callback to convert card present hardware into a boolean that indicates
1424 
1425   a media change event has happened. If you just check the GPIO you could see
1426 
1427   card 1 and then check again after card 1 was removed and card 2 was inserted
1428 
1429   and you would still see media present. Thus you need the timer tick to catch
1430 
1431   the toggle event.
1432 
1433 
1434 
1435   @param  Event                 Event whose notification function is being invoked.
1436 
1437   @param  Context               The pointer to the notification function's context,
1438 
1439                                 which is implementation-dependent. Not used.
1440 
1441 
1442 
1443 **/
1444 VOID
1445 EFIAPI
TimerCallback(IN EFI_EVENT Event,IN VOID * Context)1446 TimerCallback (
1447   IN  EFI_EVENT   Event,
1448   IN  VOID        *Context
1449   )
1450 {
1451   BOOLEAN Present;
1452 
1453   Present = CardPresent ();
1454   if (gMMCHSMedia.MediaPresent) {
1455     if (!Present && !gMediaChange) {
1456       gMediaChange = TRUE;
1457     }
1458   } else {
1459     if (Present && !gMediaChange) {
1460       gMediaChange = TRUE;
1461     }
1462   }
1463 }
1464 
1465 
1466 EFI_STATUS
1467 EFIAPI
MMCHSInitialize(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)1468 MMCHSInitialize (
1469   IN EFI_HANDLE         ImageHandle,
1470   IN EFI_SYSTEM_TABLE   *SystemTable
1471   )
1472 {
1473   EFI_STATUS  Status;
1474 
1475   Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
1476   ASSERT_EFI_ERROR(Status);
1477 
1478   ZeroMem (&gCardInfo, sizeof (CARD_INFO));
1479 
1480   Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
1481   ASSERT_EFI_ERROR (Status);
1482 
1483   Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, FixedPcdGet32 (PcdMmchsTimerFreq100NanoSeconds));
1484   ASSERT_EFI_ERROR (Status);
1485 
1486   //Publish BlockIO.
1487   Status = gBS->InstallMultipleProtocolInterfaces (
1488                   &ImageHandle,
1489                   &gEfiBlockIoProtocolGuid,    &gBlockIo,
1490                   &gEfiDevicePathProtocolGuid, &gMmcHsDevicePath,
1491                   NULL
1492                   );
1493   return Status;
1494 }
1495