]> git.proxmox.com Git - mirror_edk2.git/blob - Omap35xxPkg/MMCHSDxe/MMCHS.c
ARM Packages: Removed trailing spaces
[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), 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
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
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
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
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
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
326 GetCardConfigurationData (
327 VOID
328 )
329 {
330 UINTN BlockSize;
331 UINTN NumBlocks;
332 UINTN ClockFrequencySelect;
333
334 //Calculate BlockSize and Total number of blocks in the detected card.
335 GetBlockInformation(&BlockSize, &NumBlocks);
336 gCardInfo.BlockSize = BlockSize;
337 gCardInfo.NumBlocks = NumBlocks;
338
339 //Calculate Card clock divider value.
340 CalculateCardCLKD(&ClockFrequencySelect);
341 gCardInfo.ClockFrequencySelect = ClockFrequencySelect;
342 }
343
344
345 EFI_STATUS
346 InitializeMMCHS (
347 VOID
348 )
349 {
350 UINT8 Data = 0;
351 EFI_STATUS Status;
352
353 //Select Device group to belong to P1 device group in Power IC.
354 Data = DEV_GRP_P1;
355 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
356 ASSERT_EFI_ERROR(Status);
357
358 //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
359 Data = VSEL_3_00V;
360 Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
361 ASSERT_EFI_ERROR(Status);
362
363 //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
364 MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
365
366 // Enable WP GPIO
367 MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
368
369 // Enable Card Detect
370 Data = CARD_DETECT_ENABLE;
371 gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
372
373
374 return Status;
375 }
376
377
378 EFI_STATUS
379 PerformCardIdenfication (
380 VOID
381 )
382 {
383 EFI_STATUS Status;
384 UINTN CmdArgument = 0;
385 UINTN Response = 0;
386 UINTN RetryCount = 0;
387 BOOLEAN SDCmd8Supported = FALSE;
388
389 //Enable interrupts.
390 MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
391 CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
392
393 //Controller INIT procedure start.
394 MmioOr32 (MMCHS_CON, INIT);
395 MmioWrite32 (MMCHS_CMD, 0x00000000);
396 while (!(MmioRead32 (MMCHS_STAT) & CC));
397
398 //Wait for 1 ms
399 gBS->Stall(1000);
400
401 //Set CC bit to 0x1 to clear the flag
402 MmioOr32 (MMCHS_STAT, CC);
403
404 //Retry INIT procedure.
405 MmioWrite32 (MMCHS_CMD, 0x00000000);
406 while (!(MmioRead32 (MMCHS_STAT) & CC));
407
408 //End initialization sequence
409 MmioAnd32 (MMCHS_CON, ~INIT);
410
411 MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
412
413 //Change clock frequency to 400KHz to fit protocol
414 UpdateMMCHSClkFrequency(CLKD_400KHZ);
415
416 MmioOr32 (MMCHS_CON, OD);
417
418 //Send CMD0 command.
419 Status = SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
420 if (EFI_ERROR(Status)) {
421 DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
422 return Status;
423 }
424
425 DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 (MMCHS_RSP10)));
426
427 //Send CMD5 command.
428 Status = SendCmd (CMD5, CMD5_INT_EN, CmdArgument);
429 if (Status == EFI_SUCCESS) {
430 DEBUG ((EFI_D_ERROR, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
431 DEBUG ((EFI_D_INFO, "CMD5 response: %x\n", MmioRead32 (MMCHS_RSP10)));
432 //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
433 return EFI_UNSUPPORTED;
434 } else {
435 DEBUG ((EFI_D_INFO, "CMD5 fails. Not an SDIO card.\n"));
436 }
437
438 MmioOr32 (MMCHS_SYSCTL, SRC);
439 gBS->Stall(1000);
440 while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
441
442 //Send CMD8 command. (New v2.00 command for Voltage check)
443 //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
444 //MMC & SD1.1 card will fail this command.
445 CmdArgument = CMD8_ARG;
446 Status = SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
447 if (Status == EFI_SUCCESS) {
448 Response = MmioRead32 (MMCHS_RSP10);
449 DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
450 if (Response != CmdArgument) {
451 return EFI_DEVICE_ERROR;
452 }
453 DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
454 SDCmd8Supported = TRUE; //Supports high capacity.
455 } else {
456 DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
457 }
458
459 MmioOr32 (MMCHS_SYSCTL, SRC);
460 gBS->Stall(1000);
461 while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
462
463 //Poll till card is busy
464 while (RetryCount < MAX_RETRY_COUNT) {
465 //Send CMD55 command.
466 CmdArgument = 0;
467 Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
468 if (Status == EFI_SUCCESS) {
469 DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 (MMCHS_RSP10)));
470 gCardInfo.CardType = SD_CARD;
471 } else {
472 DEBUG ((EFI_D_INFO, "CMD55 fails.\n"));
473 gCardInfo.CardType = MMC_CARD;
474 }
475
476 //Send appropriate command for the card type which got detected.
477 if (gCardInfo.CardType == SD_CARD) {
478 CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
479
480 //Set HCS bit.
481 if (SDCmd8Supported) {
482 CmdArgument |= HCS;
483 }
484
485 Status = SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
486 if (EFI_ERROR(Status)) {
487 DEBUG ((EFI_D_INFO, "ACMD41 fails.\n"));
488 return Status;
489 }
490 ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 (MMCHS_RSP10);
491 DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
492 } else if (gCardInfo.CardType == MMC_CARD) {
493 CmdArgument = 0;
494 Status = SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
495 if (EFI_ERROR(Status)) {
496 DEBUG ((EFI_D_INFO, "CMD1 fails.\n"));
497 return Status;
498 }
499 Response = MmioRead32 (MMCHS_RSP10);
500 DEBUG ((EFI_D_INFO, "MMC card detected.. CMD1 response: %x\n", Response));
501
502 //NOTE: For now, I am skipping this since I only have an SD card.
503 //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
504 return EFI_UNSUPPORTED; //For now, MMC is not supported.
505 }
506
507 //Poll the card until it is out of its power-up sequence.
508 if (gCardInfo.OCRData.Busy == 1) {
509
510 if (SDCmd8Supported) {
511 gCardInfo.CardType = SD_CARD_2;
512 }
513
514 //Card is ready. Check CCS (Card capacity status) bit (bit#30).
515 //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
516 if (gCardInfo.OCRData.AccessMode & BIT1) {
517 gCardInfo.CardType = SD_CARD_2_HIGH;
518 DEBUG ((EFI_D_INFO, "High capacity card.\n"));
519 } else {
520 DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
521 }
522
523 break;
524 }
525
526 gBS->Stall(1000);
527 RetryCount++;
528 }
529
530 if (RetryCount == MAX_RETRY_COUNT) {
531 DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
532 return EFI_TIMEOUT;
533 }
534
535 //Read CID data.
536 CmdArgument = 0;
537 Status = SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
538 if (EFI_ERROR(Status)) {
539 DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
540 return Status;
541 }
542
543 DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
544
545 //Parse CID register data.
546 ParseCardCIDData(MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76));
547
548 //Read RCA
549 CmdArgument = 0;
550 Status = SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
551 if (EFI_ERROR(Status)) {
552 DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
553 return Status;
554 }
555
556 //Set RCA for the detected card. RCA is CMD3 response.
557 gCardInfo.RCA = (MmioRead32 (MMCHS_RSP10) >> 16);
558 DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
559
560 //MMC Bus setting change after card identification.
561 MmioAnd32 (MMCHS_CON, ~OD);
562 MmioOr32 (MMCHS_HCTL, SDVS_3_0_V);
563 UpdateMMCHSClkFrequency(CLKD_400KHZ); //Set the clock frequency to 400KHz.
564
565 return EFI_SUCCESS;
566 }
567
568
569 EFI_STATUS
570 GetCardSpecificData (
571 VOID
572 )
573 {
574 EFI_STATUS Status;
575 UINTN CmdArgument;
576
577 //Send CMD9 to retrieve CSD.
578 CmdArgument = gCardInfo.RCA << 16;
579 Status = SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
580 if (EFI_ERROR(Status)) {
581 DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
582 return Status;
583 }
584
585 //Populate 128-bit CSD register data.
586 ((UINT32 *)&(gCardInfo.CSDData))[0] = MmioRead32 (MMCHS_RSP10);
587 ((UINT32 *)&(gCardInfo.CSDData))[1] = MmioRead32 (MMCHS_RSP32);
588 ((UINT32 *)&(gCardInfo.CSDData))[2] = MmioRead32 (MMCHS_RSP54);
589 ((UINT32 *)&(gCardInfo.CSDData))[3] = MmioRead32 (MMCHS_RSP76);
590
591 DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
592
593 //Calculate total number of blocks and max. data transfer rate supported by the detected card.
594 GetCardConfigurationData();
595
596 return Status;
597 }
598
599
600 EFI_STATUS
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }