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