]> git.proxmox.com Git - mirror_edk2.git/blob - MMCHS.c
5c8e1bd746922eba3a36528d61a55e44e49999c8
[mirror_edk2.git] / 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 {
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }