1 /** @file
2 This driver is used to manage Designware SD/MMC PCI host controllers.
3
4 It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.
5
6 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
7 Copyright (c) 2017, Linaro Ltd. All rights reserved.<BR>
8
9 This program and the accompanying materials
10 are licensed and made available under the terms and conditions of the BSD License
11 which accompanies this distribution. The full text of the license may be found at
12 http://opensource.org/licenses/bsd-license.php
13
14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
15 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16
17 **/
18
19 #include "DwMmcHcDxe.h"
20
21 /**
22 Dump the content of SD/MMC host controller's Capability Register.
23
24 @param[in] Slot The slot number of the SD card to send the command to.
25 @param[in] Capability The buffer to store the capability data.
26
27 **/
28 VOID
DumpCapabilityReg(IN UINT8 Slot,IN DW_MMC_HC_SLOT_CAP * Capability)29 DumpCapabilityReg (
30 IN UINT8 Slot,
31 IN DW_MMC_HC_SLOT_CAP *Capability
32 )
33 {
34 //
35 // Dump Capability Data
36 //
37 DEBUG ((DEBUG_INFO, " == Slot [%d] Capability is 0x%x ==\n", Slot, Capability));
38 DEBUG ((DEBUG_INFO, " Base Clk Freq %dKHz\n", Capability->BaseClkFreq));
39 DEBUG ((DEBUG_INFO, " BusWidth %d\n", Capability->BusWidth));
40 DEBUG ((DEBUG_INFO, " HighSpeed Support %a\n", Capability->HighSpeed ? "TRUE" : "FALSE"));
41 DEBUG ((DEBUG_INFO, " Voltage 1.8 %a\n", Capability->Voltage18 ? "TRUE" : "FALSE"));
42 DEBUG ((DEBUG_INFO, " 64-bit Sys Bus %a\n", Capability->SysBus64 ? "TRUE" : "FALSE"));
43 DEBUG ((DEBUG_INFO, " SlotType "));
44 if (Capability->SlotType == 0x00) {
45 DEBUG ((DEBUG_INFO, "%a\n", "Removable Slot"));
46 } else if (Capability->SlotType == 0x01) {
47 DEBUG ((DEBUG_INFO, "%a\n", "Embedded Slot"));
48 } else if (Capability->SlotType == 0x02) {
49 DEBUG ((DEBUG_INFO, "%a\n", "Shared Bus Slot"));
50 } else {
51 DEBUG ((DEBUG_INFO, "%a\n", "Reserved"));
52 }
53 DEBUG ((DEBUG_INFO, " SDR50 Support %a\n", Capability->Sdr50 ? "TRUE" : "FALSE"));
54 DEBUG ((DEBUG_INFO, " SDR104 Support %a\n", Capability->Sdr104 ? "TRUE" : "FALSE"));
55 DEBUG ((DEBUG_INFO, " DDR50 Support %a\n", Capability->Ddr50 ? "TRUE" : "FALSE"));
56 return;
57 }
58
59 /**
60 Read SlotInfo register from SD/MMC host controller pci config space.
61
62 @param[in] PciIo The PCI IO protocol instance.
63 @param[out] FirstBar The buffer to store the first BAR value.
64 @param[out] SlotNum The buffer to store the supported slot number.
65
66 @retval EFI_SUCCESS The operation succeeds.
67 @retval Others The operation fails.
68
69 **/
70 EFI_STATUS
71 EFIAPI
DwMmcHcGetSlotInfo(IN EFI_PCI_IO_PROTOCOL * PciIo,OUT UINT8 * FirstBar,OUT UINT8 * SlotNum)72 DwMmcHcGetSlotInfo (
73 IN EFI_PCI_IO_PROTOCOL *PciIo,
74 OUT UINT8 *FirstBar,
75 OUT UINT8 *SlotNum
76 )
77 {
78 EFI_STATUS Status;
79 DW_MMC_HC_SLOT_INFO SlotInfo;
80
81 Status = PciIo->Pci.Read (
82 PciIo,
83 EfiPciIoWidthUint8,
84 DW_MMC_HC_SLOT_OFFSET,
85 sizeof (SlotInfo),
86 &SlotInfo
87 );
88 if (EFI_ERROR (Status)) {
89 return Status;
90 }
91
92 *FirstBar = SlotInfo.FirstBar;
93 *SlotNum = SlotInfo.SlotNum + 1;
94 ASSERT ((*FirstBar + *SlotNum) < DW_MMC_HC_MAX_SLOT);
95 return EFI_SUCCESS;
96 }
97
98 /**
99 Read/Write specified SD/MMC host controller mmio register.
100
101 @param[in] PciIo The PCI IO protocol instance.
102 @param[in] BarIndex The BAR index of the standard PCI Configuration
103 header to use as the base address for the memory
104 operation to perform.
105 @param[in] Offset The offset within the selected BAR to start the
106 memory operation.
107 @param[in] Read A boolean to indicate it's read or write operation.
108 @param[in] Count The width of the mmio register in bytes.
109 Must be 1, 2 , 4 or 8 bytes.
110 @param[in, out] Data For read operations, the destination buffer to store
111 the results. For write operations, the source buffer
112 to write data from. The caller is responsible for
113 having ownership of the data buffer and ensuring its
114 size not less than Count bytes.
115
116 @retval EFI_INVALID_PARAMETER The PciIo or Data is NULL or the Count is not valid.
117 @retval EFI_SUCCESS The read/write operation succeeds.
118 @retval Others The read/write operation fails.
119
120 **/
121 EFI_STATUS
122 EFIAPI
DwMmcHcRwMmio(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 BarIndex,IN UINT32 Offset,IN BOOLEAN Read,IN UINT8 Count,IN OUT VOID * Data)123 DwMmcHcRwMmio (
124 IN EFI_PCI_IO_PROTOCOL *PciIo,
125 IN UINT8 BarIndex,
126 IN UINT32 Offset,
127 IN BOOLEAN Read,
128 IN UINT8 Count,
129 IN OUT VOID *Data
130 )
131 {
132 EFI_STATUS Status;
133
134 if ((PciIo == NULL) || (Data == NULL)) {
135 return EFI_INVALID_PARAMETER;
136 }
137
138 if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) {
139 return EFI_INVALID_PARAMETER;
140 }
141
142 if (Read) {
143 Status = PciIo->Mem.Read (
144 PciIo,
145 EfiPciIoWidthUint8,
146 BarIndex,
147 (UINT64) Offset,
148 Count,
149 Data
150 );
151 } else {
152 Status = PciIo->Mem.Write (
153 PciIo,
154 EfiPciIoWidthUint8,
155 BarIndex,
156 (UINT64) Offset,
157 Count,
158 Data
159 );
160 }
161
162 return Status;
163 }
164
165 /**
166 Do OR operation with the value of the specified SD/MMC host controller mmio register.
167
168 @param[in] PciIo The PCI IO protocol instance.
169 @param[in] BarIndex The BAR index of the standard PCI Configuration
170 header to use as the base address for the memory
171 operation to perform.
172 @param[in] Offset The offset within the selected BAR to start the
173 memory operation.
174 @param[in] Count The width of the mmio register in bytes.
175 Must be 1, 2 , 4 or 8 bytes.
176 @param[in] OrData The pointer to the data used to do OR operation.
177 The caller is responsible for having ownership of
178 the data buffer and ensuring its size not less than
179 Count bytes.
180
181 @retval EFI_INVALID_PARAMETER The PciIo or OrData is NULL or the Count is not valid.
182 @retval EFI_SUCCESS The OR operation succeeds.
183 @retval Others The OR operation fails.
184
185 **/
186 EFI_STATUS
187 EFIAPI
DwMmcHcOrMmio(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 BarIndex,IN UINT32 Offset,IN UINT8 Count,IN VOID * OrData)188 DwMmcHcOrMmio (
189 IN EFI_PCI_IO_PROTOCOL *PciIo,
190 IN UINT8 BarIndex,
191 IN UINT32 Offset,
192 IN UINT8 Count,
193 IN VOID *OrData
194 )
195 {
196 EFI_STATUS Status;
197 UINT64 Data;
198 UINT64 Or;
199
200 Status = DwMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);
201 if (EFI_ERROR (Status)) {
202 return Status;
203 }
204
205 if (Count == 1) {
206 Or = *(UINT8*) OrData;
207 } else if (Count == 2) {
208 Or = *(UINT16*) OrData;
209 } else if (Count == 4) {
210 Or = *(UINT32*) OrData;
211 } else if (Count == 8) {
212 Or = *(UINT64*) OrData;
213 } else {
214 return EFI_INVALID_PARAMETER;
215 }
216
217 Data |= Or;
218 Status = DwMmcHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);
219
220 return Status;
221 }
222
223 /**
224 Do AND operation with the value of the specified SD/MMC host controller mmio register.
225
226 @param[in] PciIo The PCI IO protocol instance.
227 @param[in] BarIndex The BAR index of the standard PCI Configuration
228 header to use as the base address for the memory
229 operation to perform.
230 @param[in] Offset The offset within the selected BAR to start the
231 memory operation.
232 @param[in] Count The width of the mmio register in bytes.
233 Must be 1, 2 , 4 or 8 bytes.
234 @param[in] AndData The pointer to the data used to do AND operation.
235 The caller is responsible for having ownership of
236 the data buffer and ensuring its size not less than
237 Count bytes.
238
239 @retval EFI_INVALID_PARAMETER The PciIo or AndData is NULL or the Count is not valid.
240 @retval EFI_SUCCESS The AND operation succeeds.
241 @retval Others The AND operation fails.
242
243 **/
244 EFI_STATUS
245 EFIAPI
DwMmcHcAndMmio(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 BarIndex,IN UINT32 Offset,IN UINT8 Count,IN VOID * AndData)246 DwMmcHcAndMmio (
247 IN EFI_PCI_IO_PROTOCOL *PciIo,
248 IN UINT8 BarIndex,
249 IN UINT32 Offset,
250 IN UINT8 Count,
251 IN VOID *AndData
252 )
253 {
254 EFI_STATUS Status;
255 UINT64 Data;
256 UINT64 And;
257
258 Status = DwMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);
259 if (EFI_ERROR (Status)) {
260 return Status;
261 }
262
263 if (Count == 1) {
264 And = *(UINT8*) AndData;
265 } else if (Count == 2) {
266 And = *(UINT16*) AndData;
267 } else if (Count == 4) {
268 And = *(UINT32*) AndData;
269 } else if (Count == 8) {
270 And = *(UINT64*) AndData;
271 } else {
272 return EFI_INVALID_PARAMETER;
273 }
274
275 Data &= And;
276 Status = DwMmcHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);
277
278 return Status;
279 }
280
281 /**
282 Wait for the value of the specified MMIO register set to the test value.
283
284 @param[in] PciIo The PCI IO protocol instance.
285 @param[in] BarIndex The BAR index of the standard PCI Configuration
286 header to use as the base address for the memory
287 operation to perform.
288 @param[in] Offset The offset within the selected BAR to start the
289 memory operation.
290 @param[in] Count The width of the mmio register in bytes.
291 Must be 1, 2, 4 or 8 bytes.
292 @param[in] MaskValue The mask value of memory.
293 @param[in] TestValue The test value of memory.
294
295 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.
296 @retval EFI_SUCCESS The MMIO register has expected value.
297 @retval Others The MMIO operation fails.
298
299 **/
300 EFI_STATUS
301 EFIAPI
DwMmcHcCheckMmioSet(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 BarIndex,IN UINT32 Offset,IN UINT8 Count,IN UINT64 MaskValue,IN UINT64 TestValue)302 DwMmcHcCheckMmioSet (
303 IN EFI_PCI_IO_PROTOCOL *PciIo,
304 IN UINT8 BarIndex,
305 IN UINT32 Offset,
306 IN UINT8 Count,
307 IN UINT64 MaskValue,
308 IN UINT64 TestValue
309 )
310 {
311 EFI_STATUS Status;
312 UINT64 Value;
313
314 //
315 // Access PCI MMIO space to see if the value is the tested one.
316 //
317 Value = 0;
318 Status = DwMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Value);
319 if (EFI_ERROR (Status)) {
320 return Status;
321 }
322
323 Value &= MaskValue;
324
325 if (Value == TestValue) {
326 return EFI_SUCCESS;
327 }
328
329 return EFI_NOT_READY;
330 }
331
332 /**
333 Wait for the value of the specified MMIO register set to the test value.
334
335 @param[in] PciIo The PCI IO protocol instance.
336 @param[in] BarIndex The BAR index of the standard PCI Configuration
337 header to use as the base address for the memory
338 operation to perform.
339 @param[in] Offset The offset within the selected BAR to start the
340 memory operation.
341 @param[in] Count The width of the mmio register in bytes.
342 Must be 1, 2, 4 or 8 bytes.
343 @param[in] MaskValue The mask value of memory.
344 @param[in] TestValue The test value of memory.
345 @param[in] Timeout The time out value for wait memory set, uses 1
346 microsecond as a unit.
347
348 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout
349 range.
350 @retval EFI_SUCCESS The MMIO register has expected value.
351 @retval Others The MMIO operation fails.
352
353 **/
354 EFI_STATUS
355 EFIAPI
DwMmcHcWaitMmioSet(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 BarIndex,IN UINT32 Offset,IN UINT8 Count,IN UINT64 MaskValue,IN UINT64 TestValue,IN UINT64 Timeout)356 DwMmcHcWaitMmioSet (
357 IN EFI_PCI_IO_PROTOCOL *PciIo,
358 IN UINT8 BarIndex,
359 IN UINT32 Offset,
360 IN UINT8 Count,
361 IN UINT64 MaskValue,
362 IN UINT64 TestValue,
363 IN UINT64 Timeout
364 )
365 {
366 EFI_STATUS Status;
367 BOOLEAN InfiniteWait;
368
369 if (Timeout == 0) {
370 InfiniteWait = TRUE;
371 } else {
372 InfiniteWait = FALSE;
373 }
374
375 while (InfiniteWait || (Timeout > 0)) {
376 Status = DwMmcHcCheckMmioSet (
377 PciIo,
378 BarIndex,
379 Offset,
380 Count,
381 MaskValue,
382 TestValue
383 );
384 if (Status != EFI_NOT_READY) {
385 return Status;
386 }
387
388 //
389 // Stall for 1 microsecond.
390 //
391 gBS->Stall (1);
392
393 Timeout--;
394 }
395
396 return EFI_TIMEOUT;
397 }
398
399 /**
400 Set all interrupt status bits in Normal and Error Interrupt Status Enable
401 register.
402
403 @param[in] PciIo The PCI IO protocol instance.
404 @param[in] Slot The slot number of the SD card to send the command to.
405
406 @retval EFI_SUCCESS The operation executes successfully.
407 @retval Others The operation fails.
408
409 **/
410 EFI_STATUS
DwMmcHcEnableInterrupt(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot)411 DwMmcHcEnableInterrupt (
412 IN EFI_PCI_IO_PROTOCOL *PciIo,
413 IN UINT8 Slot
414 )
415 {
416 EFI_STATUS Status;
417 UINT32 IntStatus;
418 UINT32 IdIntEn;
419 UINT32 IdSts;
420
421 //
422 // Enable all bits in Interrupt Mask Register
423 //
424 IntStatus = 0;
425 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_INTMASK, FALSE, sizeof (IntStatus), &IntStatus);
426 if (EFI_ERROR (Status)) {
427 return Status;
428 }
429
430 //
431 // Clear status in Interrupt Status Register
432 //
433 IntStatus = ~0;
434 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_RINTSTS, FALSE, sizeof (IntStatus), &IntStatus);
435 if (EFI_ERROR (Status)) {
436 return Status;
437 }
438
439 IdIntEn = ~0;
440 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_IDINTEN, FALSE, sizeof (IdIntEn), &IdIntEn);
441 if (EFI_ERROR (Status)) {
442 DEBUG ((DEBUG_ERROR, "DwMmcHcReset: init dma interrupts fail: %r\n", Status));
443 return Status;
444 }
445
446 IdSts = ~0;
447 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_IDSTS, FALSE, sizeof (IdSts), &IdSts);
448 return Status;
449 }
450
451 /**
452 Get the capability data from the specified slot.
453
454 @param[in] PciIo The PCI IO protocol instance.
455 @param[in] Slot The slot number of the SD card to send the command to.
456 @param[out] Capability The buffer to store the capability data.
457
458 @retval EFI_SUCCESS The operation executes successfully.
459 @retval Others The operation fails.
460
461 **/
462 EFI_STATUS
DwMmcHcGetCapability(IN EFI_PCI_IO_PROTOCOL * PciIo,IN EFI_HANDLE Controller,IN UINT8 Slot,OUT DW_MMC_HC_SLOT_CAP * Capacity)463 DwMmcHcGetCapability (
464 IN EFI_PCI_IO_PROTOCOL *PciIo,
465 IN EFI_HANDLE Controller,
466 IN UINT8 Slot,
467 OUT DW_MMC_HC_SLOT_CAP *Capacity
468 )
469 {
470 PLATFORM_DW_MMC_PROTOCOL *PlatformDwMmc;
471 EFI_STATUS Status;
472
473 if (Capacity == NULL) {
474 return EFI_INVALID_PARAMETER;
475 }
476 Status = gBS->LocateProtocol (
477 &gPlatformDwMmcProtocolGuid,
478 NULL,
479 (VOID **) &PlatformDwMmc
480 );
481 if (EFI_ERROR (Status)) {
482 return Status;
483 }
484 Status = PlatformDwMmc->GetCapability (Controller, Slot, Capacity);
485 return Status;
486 }
487
488 /**
489 Get the maximum current capability data from the specified slot.
490
491 @param[in] PciIo The PCI IO protocol instance.
492 @param[in] Slot The slot number of the SD card to send the command to.
493 @param[out] MaxCurrent The buffer to store the maximum current capability data.
494
495 @retval EFI_SUCCESS The operation executes successfully.
496 @retval Others The operation fails.
497
498 **/
499 EFI_STATUS
DwMmcHcGetMaxCurrent(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,OUT UINT64 * MaxCurrent)500 DwMmcHcGetMaxCurrent (
501 IN EFI_PCI_IO_PROTOCOL *PciIo,
502 IN UINT8 Slot,
503 OUT UINT64 *MaxCurrent
504 )
505 {
506 return EFI_SUCCESS;
507 }
508
509 /**
510 Detect whether there is a SD/MMC card attached at the specified SD/MMC host controller
511 slot.
512
513 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.
514
515 @param[in] PciIo The PCI IO protocol instance.
516 @param[in] Slot The slot number of the SD card to send the command to.
517 @param[out] MediaPresent The pointer to the media present boolean value.
518
519 @retval EFI_SUCCESS There is no media change happened.
520 @retval EFI_MEDIA_CHANGED There is media change happened.
521 @retval Others The detection fails.
522
523 **/
524 EFI_STATUS
DwMmcHcCardDetect(IN EFI_PCI_IO_PROTOCOL * PciIo,IN EFI_HANDLE Controller,IN UINT8 Slot,OUT BOOLEAN * MediaPresent)525 DwMmcHcCardDetect (
526 IN EFI_PCI_IO_PROTOCOL *PciIo,
527 IN EFI_HANDLE Controller,
528 IN UINT8 Slot,
529 OUT BOOLEAN *MediaPresent
530 )
531 {
532 PLATFORM_DW_MMC_PROTOCOL *PlatformDwMmc;
533 EFI_STATUS Status;
534
535 if (MediaPresent == NULL) {
536 return EFI_INVALID_PARAMETER;
537 }
538 Status = gBS->LocateProtocol (
539 &gPlatformDwMmcProtocolGuid,
540 NULL,
541 (VOID **) &PlatformDwMmc
542 );
543 if (EFI_ERROR (Status)) {
544 return Status;
545 }
546 *MediaPresent = PlatformDwMmc->CardDetect (Controller, Slot);
547 return EFI_SUCCESS;
548 }
549
550 STATIC
551 EFI_STATUS
DwMmcHcUpdateClock(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot)552 DwMmcHcUpdateClock (
553 IN EFI_PCI_IO_PROTOCOL *PciIo,
554 IN UINT8 Slot
555 )
556 {
557 EFI_STATUS Status;
558 UINT32 Cmd;
559 UINT32 IntStatus;
560
561 Cmd = BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_UPDATE_CLOCK_ONLY |
562 BIT_CMD_START;
563 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CMD, FALSE, sizeof (Cmd), &Cmd);
564 if (EFI_ERROR (Status)) {
565 return Status;
566 }
567 while (1) {
568 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CMD, TRUE, sizeof (Cmd), &Cmd);
569 if (EFI_ERROR (Status)) {
570 return Status;
571 }
572 if (!(Cmd & CMD_START_BIT)) {
573 break;
574 }
575 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_RINTSTS, TRUE, sizeof (IntStatus), &IntStatus);
576 if (EFI_ERROR (Status)) {
577 return Status;
578 }
579 if (IntStatus & DW_MMC_INT_HLE) {
580 DEBUG ((DEBUG_ERROR, "DwMmcHcUpdateClock: failed to update mmc clock frequency\n"));
581 return EFI_DEVICE_ERROR;
582 }
583 }
584 return EFI_SUCCESS;
585
586 }
587
588 /**
589 Stop SD/MMC card clock.
590
591 @param[in] PciIo The PCI IO protocol instance.
592 @param[in] Slot The slot number of the SD card to send the command to.
593
594 @retval EFI_SUCCESS Succeed to stop SD/MMC clock.
595 @retval Others Fail to stop SD/MMC clock.
596
597 **/
598 EFI_STATUS
DwMmcHcStopClock(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot)599 DwMmcHcStopClock (
600 IN EFI_PCI_IO_PROTOCOL *PciIo,
601 IN UINT8 Slot
602 )
603 {
604 EFI_STATUS Status;
605 UINT32 ClkEna;
606
607 // Disable MMC clock first
608 ClkEna = 0;
609 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CLKENA, FALSE, sizeof (ClkEna), &ClkEna);
610 if (EFI_ERROR (Status)) {
611 return Status;
612 }
613 Status = DwMmcHcUpdateClock (PciIo, Slot);
614 if (EFI_ERROR (Status)) {
615 return Status;
616 }
617 return Status;
618 }
619
620 /**
621 SD/MMC card clock supply.
622
623 @param[in] PciIo The PCI IO protocol instance.
624 @param[in] Slot The slot number of the SD card to send the command to.
625 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.
626 @param[in] Capability The capability of the slot.
627
628 @retval EFI_SUCCESS The clock is supplied successfully.
629 @retval Others The clock isn't supplied successfully.
630
631 **/
632 EFI_STATUS
DwMmcHcClockSupply(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN UINT64 ClockFreq,IN DW_MMC_HC_SLOT_CAP Capability)633 DwMmcHcClockSupply (
634 IN EFI_PCI_IO_PROTOCOL *PciIo,
635 IN UINT8 Slot,
636 IN UINT64 ClockFreq,
637 IN DW_MMC_HC_SLOT_CAP Capability
638 )
639 {
640 EFI_STATUS Status;
641 UINT32 BaseClkFreq;
642 UINT32 SettingFreq;
643 UINT32 Divisor;
644 UINT32 Remainder;
645 UINT32 MmcStatus;
646 UINT32 ClkEna;
647 UINT32 ClkSrc;
648
649 //
650 // Calculate a divisor for SD clock frequency
651 //
652 ASSERT (Capability.BaseClkFreq != 0);
653
654 BaseClkFreq = Capability.BaseClkFreq;
655 if (ClockFreq == 0) {
656 return EFI_INVALID_PARAMETER;
657 }
658
659 if (ClockFreq > BaseClkFreq) {
660 ClockFreq = BaseClkFreq;
661 }
662
663 //
664 // Calculate the divisor of base frequency.
665 //
666 Divisor = 0;
667 SettingFreq = BaseClkFreq;
668 while (ClockFreq < SettingFreq) {
669 Divisor++;
670
671 SettingFreq = BaseClkFreq / (2 * Divisor);
672 Remainder = BaseClkFreq % (2 * Divisor);
673 if ((ClockFreq == SettingFreq) && (Remainder == 0)) {
674 break;
675 }
676 if ((ClockFreq == SettingFreq) && (Remainder != 0)) {
677 SettingFreq ++;
678 }
679 }
680
681 DEBUG ((DEBUG_INFO, "BaseClkFreq %dKHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));
682
683 // Wait until MMC is idle
684 do {
685 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_STATUS, TRUE, sizeof (MmcStatus), &MmcStatus);
686 if (EFI_ERROR (Status)) {
687 return Status;
688 }
689 } while (MmcStatus & DW_MMC_STS_DATA_BUSY);
690
691 do {
692 Status = DwMmcHcStopClock (PciIo, Slot);
693 } while (EFI_ERROR (Status));
694
695 do {
696 ClkSrc = 0;
697 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CLKSRC, FALSE, sizeof (ClkSrc), &ClkSrc);
698 if (EFI_ERROR (Status)) {
699 continue;
700 }
701 // Set clock divisor
702 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CLKDIV, FALSE, sizeof (Divisor), &Divisor);
703 if (EFI_ERROR (Status)) {
704 continue;
705 }
706 // Enable MMC clock
707 ClkEna = 1;
708 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CLKENA, FALSE, sizeof (ClkEna), &ClkEna);
709 if (EFI_ERROR (Status)) {
710 continue;
711 }
712 Status = DwMmcHcUpdateClock (PciIo, Slot);
713 } while (EFI_ERROR (Status));
714
715 return EFI_SUCCESS;
716 }
717
718 /**
719 SD/MMC bus power control.
720
721 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
722
723 @param[in] PciIo The PCI IO protocol instance.
724 @param[in] Slot The slot number of the SD card to send the command to.
725 @param[in] PowerCtrl The value setting to the power control register.
726
727 @retval TRUE There is a SD/MMC card attached.
728 @retval FALSE There is no a SD/MMC card attached.
729
730 **/
731 EFI_STATUS
DwMmcHcPowerControl(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN UINT8 PowerCtrl)732 DwMmcHcPowerControl (
733 IN EFI_PCI_IO_PROTOCOL *PciIo,
734 IN UINT8 Slot,
735 IN UINT8 PowerCtrl
736 )
737 {
738 return EFI_SUCCESS;
739 }
740
741 /**
742 Set the SD/MMC bus width.
743
744 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.
745
746 @param[in] PciIo The PCI IO protocol instance.
747 @param[in] Slot The slot number of the SD card to send the command to.
748 @param[in] BusWidth The bus width used by the SD/MMC device, it must be 1, 4 or 8.
749
750 @retval EFI_SUCCESS The bus width is set successfully.
751 @retval Others The bus width isn't set successfully.
752
753 **/
754 EFI_STATUS
DwMmcHcSetBusWidth(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN BOOLEAN IsDdr,IN UINT16 BusWidth)755 DwMmcHcSetBusWidth (
756 IN EFI_PCI_IO_PROTOCOL *PciIo,
757 IN UINT8 Slot,
758 IN BOOLEAN IsDdr,
759 IN UINT16 BusWidth
760 )
761 {
762 EFI_STATUS Status;
763 UINT32 Ctype;
764 UINT32 Uhs;
765
766 switch (BusWidth) {
767 case 1:
768 Ctype = MMC_1BIT_MODE;
769 break;
770 case 4:
771 Ctype = MMC_4BIT_MODE;
772 break;
773 case 8:
774 Ctype = MMC_8BIT_MODE;
775 break;
776 default:
777 return EFI_INVALID_PARAMETER;
778 }
779 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CTYPE, FALSE, sizeof (Ctype), &Ctype);
780 if (EFI_ERROR (Status)) {
781 return Status;
782 }
783 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_UHSREG, TRUE, sizeof (Uhs), &Uhs);
784 if (EFI_ERROR (Status)) {
785 return Status;
786 }
787 if (IsDdr) {
788 Uhs |= UHS_DDR_MODE;
789 } else {
790 Uhs &= ~(UHS_DDR_MODE);
791 }
792 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_UHSREG, FALSE, sizeof (Uhs), &Uhs);
793 return Status;
794 }
795
796 /**
797 Supply SD/MMC card with lowest clock frequency at initialization.
798
799 @param[in] PciIo The PCI IO protocol instance.
800 @param[in] Slot The slot number of the SD card to send the command to.
801 @param[in] Capability The capability of the slot.
802
803 @retval EFI_SUCCESS The clock is supplied successfully.
804 @retval Others The clock isn't supplied successfully.
805
806 **/
807 EFI_STATUS
DwMmcHcInitClockFreq(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN DW_MMC_HC_SLOT_CAP Capability)808 DwMmcHcInitClockFreq (
809 IN EFI_PCI_IO_PROTOCOL *PciIo,
810 IN UINT8 Slot,
811 IN DW_MMC_HC_SLOT_CAP Capability
812 )
813 {
814 EFI_STATUS Status;
815 UINT32 InitFreq;
816
817 //
818 // Calculate a divisor for SD clock frequency
819 //
820 if (Capability.BaseClkFreq == 0) {
821 //
822 // Don't support get Base Clock Frequency information via another method
823 //
824 return EFI_UNSUPPORTED;
825 }
826 //
827 // Supply 400KHz clock frequency at initialization phase.
828 //
829 InitFreq = DWMMC_INIT_CLOCK_FREQ;
830 Status = DwMmcHcClockSupply (PciIo, Slot, InitFreq, Capability);
831 if (EFI_ERROR (Status)) {
832 return Status;
833 }
834 MicroSecondDelay (100);
835 return Status;
836 }
837
838 /**
839 Supply SD/MMC card with maximum voltage at initialization.
840
841 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.
842
843 @param[in] PciIo The PCI IO protocol instance.
844 @param[in] Slot The slot number of the SD card to send the command to.
845 @param[in] Capability The capability of the slot.
846
847 @retval EFI_SUCCESS The voltage is supplied successfully.
848 @retval Others The voltage isn't supplied successfully.
849
850 **/
851 EFI_STATUS
DwMmcHcInitPowerVoltage(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN DW_MMC_HC_SLOT_CAP Capability)852 DwMmcHcInitPowerVoltage (
853 IN EFI_PCI_IO_PROTOCOL *PciIo,
854 IN UINT8 Slot,
855 IN DW_MMC_HC_SLOT_CAP Capability
856 )
857 {
858 EFI_STATUS Status;
859 UINT32 Data;
860
861 Data = 0x1;
862 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_PWREN, FALSE, sizeof (Data), &Data);
863
864 if (EFI_ERROR (Status)) {
865 DEBUG ((DEBUG_ERROR, "DwMmcHcInitPowerVoltage: enable power fails: %r\n", Status));
866 return Status;
867 }
868
869 Data = DW_MMC_CTRL_RESET_ALL;
870 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CTRL, FALSE, sizeof (Data), &Data);
871 if (EFI_ERROR (Status)) {
872 DEBUG ((DEBUG_ERROR, "DwMmcHcInitPowerVoltage: reset fails: %r\n", Status));
873 return Status;
874 }
875 Status = DwMmcHcWaitMmioSet (
876 PciIo,
877 Slot,
878 DW_MMC_CTRL,
879 sizeof (Data),
880 DW_MMC_CTRL_RESET_ALL,
881 0x00,
882 DW_MMC_HC_GENERIC_TIMEOUT
883 );
884 if (EFI_ERROR (Status)) {
885 DEBUG ((DEBUG_INFO, "DwMmcHcInitPowerVoltage: reset done with %r\n", Status));
886 return Status;
887 }
888
889 Data = DW_MMC_CTRL_INT_EN;
890 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_CTRL, FALSE, sizeof (Data), &Data);
891 return Status;
892 }
893
894 /**
895 Initialize the Timeout Control register with most conservative value at initialization.
896
897 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.
898
899 @param[in] PciIo The PCI IO protocol instance.
900 @param[in] Slot The slot number of the SD card to send the command to.
901
902 @retval EFI_SUCCESS The timeout control register is configured successfully.
903 @retval Others The timeout control register isn't configured successfully.
904
905 **/
906 EFI_STATUS
DwMmcHcInitTimeoutCtrl(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot)907 DwMmcHcInitTimeoutCtrl (
908 IN EFI_PCI_IO_PROTOCOL *PciIo,
909 IN UINT8 Slot
910 )
911 {
912 EFI_STATUS Status;
913 UINT32 Data;
914
915 Data = ~0;
916 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_TMOUT, FALSE, sizeof (Data), &Data);
917 if (EFI_ERROR (Status)) {
918 DEBUG ((DEBUG_ERROR, "DwMmcHcInitTimeoutCtrl: set timeout fails: %r\n", Status));
919 return Status;
920 }
921
922 Data = 0x00FFFFFF;
923 Status = DwMmcHcRwMmio (PciIo, Slot, DW_MMC_DEBNCE, FALSE, sizeof (Data), &Data);
924 return Status;
925 }
926
927 /**
928 Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value
929 at initialization.
930
931 @param[in] PciIo The PCI IO protocol instance.
932 @param[in] Slot The slot number of the SD card to send the command to.
933 @param[in] Capability The capability of the slot.
934
935 @retval EFI_SUCCESS The host controller is initialized successfully.
936 @retval Others The host controller isn't initialized successfully.
937
938 **/
939 EFI_STATUS
DwMmcHcInitHost(IN EFI_PCI_IO_PROTOCOL * PciIo,IN UINT8 Slot,IN DW_MMC_HC_SLOT_CAP Capability)940 DwMmcHcInitHost (
941 IN EFI_PCI_IO_PROTOCOL *PciIo,
942 IN UINT8 Slot,
943 IN DW_MMC_HC_SLOT_CAP Capability
944 )
945 {
946 EFI_STATUS Status;
947
948 Status = DwMmcHcInitPowerVoltage (PciIo, Slot, Capability);
949 if (EFI_ERROR (Status)) {
950 return Status;
951 }
952 return Status;
953 }
954
955 EFI_STATUS
DwMmcHcStartDma(IN DW_MMC_HC_PRIVATE_DATA * Private,IN DW_MMC_HC_TRB * Trb)956 DwMmcHcStartDma (
957 IN DW_MMC_HC_PRIVATE_DATA *Private,
958 IN DW_MMC_HC_TRB *Trb
959 )
960 {
961 EFI_STATUS Status;
962 EFI_PCI_IO_PROTOCOL *PciIo;
963 UINT32 Ctrl;
964 UINT32 Bmod;
965
966 PciIo = Trb->Private->PciIo;
967
968 // Reset DMA
969 Ctrl = DW_MMC_CTRL_DMA_RESET;
970 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CTRL, FALSE, sizeof (Ctrl), &Ctrl);
971 if (EFI_ERROR (Status)) {
972 DEBUG ((DEBUG_ERROR, "DwMmcHcStartDma: reset fails: %r\n", Status));
973 return Status;
974 }
975 Status = DwMmcHcWaitMmioSet (
976 PciIo,
977 Trb->Slot,
978 DW_MMC_CTRL,
979 sizeof (Ctrl),
980 DW_MMC_CTRL_DMA_RESET,
981 0x00,
982 DW_MMC_HC_GENERIC_TIMEOUT
983 );
984 if (EFI_ERROR (Status)) {
985 DEBUG ((DEBUG_INFO, "DwMmcHcStartDma: reset done with %r\n", Status));
986 return Status;
987 }
988 Bmod = DW_MMC_IDMAC_SWRESET;
989 Status = DwMmcHcOrMmio (PciIo, Trb->Slot, DW_MMC_BMOD, sizeof (Bmod), &Bmod);
990 if (EFI_ERROR (Status)) {
991 DEBUG ((DEBUG_ERROR, "DwMmcHcStartDma: set BMOD fail: %r\n", Status));
992 return Status;
993 }
994
995 // Select IDMAC
996 Ctrl = DW_MMC_CTRL_IDMAC_EN;
997 Status = DwMmcHcOrMmio (PciIo, Trb->Slot, DW_MMC_CTRL, sizeof (Ctrl), &Ctrl);
998 if (EFI_ERROR (Status)) {
999 DEBUG ((DEBUG_ERROR, "DwMmcHcStartDma: init IDMAC fail: %r\n", Status));
1000 return Status;
1001 }
1002
1003 // Enable IDMAC
1004 Bmod = DW_MMC_IDMAC_ENABLE | DW_MMC_IDMAC_FB;
1005 Status = DwMmcHcOrMmio (PciIo, Trb->Slot, DW_MMC_BMOD, sizeof (Bmod), &Bmod);
1006 if (EFI_ERROR (Status)) {
1007 DEBUG ((DEBUG_ERROR, "DwMmcHcReset: set BMOD failure: %r\n", Status));
1008 return Status;
1009 }
1010 return Status;
1011 }
1012
1013 EFI_STATUS
DwMmcHcStopDma(IN DW_MMC_HC_PRIVATE_DATA * Private,IN DW_MMC_HC_TRB * Trb)1014 DwMmcHcStopDma (
1015 IN DW_MMC_HC_PRIVATE_DATA *Private,
1016 IN DW_MMC_HC_TRB *Trb
1017 )
1018 {
1019 EFI_STATUS Status;
1020 EFI_PCI_IO_PROTOCOL *PciIo;
1021 UINT32 Ctrl;
1022 UINT32 Bmod;
1023
1024 PciIo = Trb->Private->PciIo;
1025
1026 // Disable and reset IDMAC
1027 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CTRL, TRUE, sizeof (Ctrl), &Ctrl);
1028 if (EFI_ERROR (Status)) {
1029 return Status;
1030 }
1031 Ctrl &= ~DW_MMC_CTRL_IDMAC_EN;
1032 Ctrl |= DW_MMC_CTRL_DMA_RESET;
1033 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CTRL, FALSE, sizeof (Ctrl), &Ctrl);
1034 if (EFI_ERROR (Status)) {
1035 return Status;
1036 }
1037 // Stop IDMAC
1038 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BMOD, TRUE, sizeof (Bmod), &Bmod);
1039 if (EFI_ERROR (Status)) {
1040 return Status;
1041 }
1042 Bmod &= ~(DW_MMC_BMOD_FB | DW_MMC_BMOD_DE);
1043 Bmod |= DW_MMC_BMOD_SWR;
1044 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BMOD, FALSE, sizeof (Bmod), &Bmod);
1045 if (EFI_ERROR (Status)) {
1046 return Status;
1047 }
1048 return Status;
1049 }
1050
1051 /**
1052 Build DMA descriptor table for transfer.
1053
1054 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1055
1056 @retval EFI_SUCCESS The DMA descriptor table is created successfully.
1057 @retval Others The DMA descriptor table isn't created successfully.
1058
1059 **/
1060 EFI_STATUS
BuildDmaDescTable(IN DW_MMC_HC_TRB * Trb)1061 BuildDmaDescTable (
1062 IN DW_MMC_HC_TRB *Trb
1063 )
1064 {
1065 EFI_PHYSICAL_ADDRESS Data;
1066 UINT64 DataLen;
1067 UINT64 Entries;
1068 UINT32 Index;
1069 UINT64 Remaining;
1070 UINTN TableSize;
1071 EFI_PCI_IO_PROTOCOL *PciIo;
1072 EFI_STATUS Status;
1073 UINTN Bytes;
1074 UINTN Blocks;
1075 DW_MMC_HC_DMA_DESC_LINE *DmaDesc;
1076 UINT32 DmaDescPhy;
1077 UINT32 Idsts;
1078 UINT32 BytCnt;
1079 UINT32 BlkSize;
1080
1081 Data = Trb->DataPhy;
1082 DataLen = Trb->DataLen;
1083 PciIo = Trb->Private->PciIo;
1084 //
1085 // Only support 32bit DMA Descriptor Table
1086 //
1087 if ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul)) {
1088 return EFI_INVALID_PARAMETER;
1089 }
1090 //
1091 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)
1092 // for 32-bit address descriptor table.
1093 //
1094 if ((Data & (BIT0 | BIT1)) != 0) {
1095 DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct DMA desc is not aligned to 4 bytes boundary!\n", Data));
1096 }
1097
1098 Entries = (DataLen + DWMMC_DMA_BUF_SIZE - 1) / DWMMC_DMA_BUF_SIZE;
1099 TableSize = Entries * sizeof (DW_MMC_HC_DMA_DESC_LINE);
1100 Blocks = (DataLen + DW_MMC_BLOCK_SIZE - 1) / DW_MMC_BLOCK_SIZE;
1101
1102 Trb->DmaDescPages = (UINT32)EFI_SIZE_TO_PAGES (Entries * DWMMC_DMA_BUF_SIZE);
1103 Status = PciIo->AllocateBuffer (
1104 PciIo,
1105 AllocateAnyPages,
1106 EfiBootServicesData,
1107 EFI_SIZE_TO_PAGES (TableSize),
1108 (VOID **)&Trb->DmaDesc,
1109 0
1110 );
1111 if (EFI_ERROR (Status)) {
1112 return EFI_OUT_OF_RESOURCES;
1113 }
1114 ZeroMem (Trb->DmaDesc, TableSize);
1115 Bytes = TableSize;
1116 Status = PciIo->Map (
1117 PciIo,
1118 EfiPciIoOperationBusMasterCommonBuffer,
1119 Trb->DmaDesc,
1120 &Bytes,
1121 &Trb->DmaDescPhy,
1122 &Trb->DmaMap
1123 );
1124
1125 if (EFI_ERROR (Status) || (Bytes != TableSize)) {
1126 //
1127 // Map error or unable to map the whole RFis buffer into a contiguous region.
1128 //
1129 PciIo->FreeBuffer (
1130 PciIo,
1131 EFI_SIZE_TO_PAGES (TableSize),
1132 Trb->DmaDesc
1133 );
1134 return EFI_OUT_OF_RESOURCES;
1135 }
1136
1137 if ((UINT64)(UINTN)Trb->DmaDescPhy > 0x100000000ul) {
1138 //
1139 // The DMA doesn't support 64bit addressing.
1140 //
1141 PciIo->Unmap (
1142 PciIo,
1143 Trb->DmaMap
1144 );
1145 #if 0
1146 PciIo->FreeBuffer (
1147 PciIo,
1148 EFI_SIZE_TO_PAGES (TableSize),
1149 Trb->DmaDesc
1150 );
1151 #endif
1152 return EFI_DEVICE_ERROR;
1153 }
1154
1155 if (DataLen < DW_MMC_BLOCK_SIZE) {
1156 BlkSize = DataLen;
1157 BytCnt = DataLen;
1158 Remaining = DataLen;
1159 } else {
1160 BlkSize = DW_MMC_BLOCK_SIZE;
1161 BytCnt = DW_MMC_BLOCK_SIZE * Blocks;
1162 Remaining = DW_MMC_BLOCK_SIZE * Blocks;
1163 }
1164 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BLKSIZ, FALSE, sizeof (BlkSize), &BlkSize);
1165 if (EFI_ERROR (Status)) {
1166 DEBUG ((DEBUG_ERROR, "BuildDmaDescTable: set block size fails: %r\n", Status));
1167 return Status;
1168 }
1169 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BYTCNT, FALSE, sizeof (BytCnt), &BytCnt);
1170 if (EFI_ERROR (Status)) {
1171 return Status;
1172 }
1173 DmaDesc = Trb->DmaDesc;
1174 for (Index = 0; Index < Entries; Index++, DmaDesc++) {
1175 DmaDesc->Des0 = DW_MMC_IDMAC_DES0_OWN | DW_MMC_IDMAC_DES0_CH |
1176 DW_MMC_IDMAC_DES0_DIC;
1177 DmaDesc->Des1 = DW_MMC_IDMAC_DES1_BS1 (DWMMC_DMA_BUF_SIZE);
1178 // Buffer Address
1179 DmaDesc->Des2 = (UINT32)((UINTN)Trb->DataPhy + (DWMMC_DMA_BUF_SIZE * Index));
1180 // Next Descriptor Address
1181 DmaDesc->Des3 = (UINT32)((UINTN)Trb->DmaDescPhy + sizeof (DW_MMC_HC_DMA_DESC_LINE) * (Index + 1));
1182 Remaining = Remaining - DWMMC_DMA_BUF_SIZE;
1183 }
1184 // First Descriptor
1185 Trb->DmaDesc[0].Des0 |= DW_MMC_IDMAC_DES0_FS;
1186 // Last Descriptor
1187 Trb->DmaDesc[Entries - 1].Des0 &= ~(DW_MMC_IDMAC_DES0_CH | DW_MMC_IDMAC_DES0_DIC);
1188 Trb->DmaDesc[Entries - 1].Des0 |= DW_MMC_IDMAC_DES0_OWN | DW_MMC_IDMAC_DES0_LD;
1189 Trb->DmaDesc[Entries - 1].Des1 = DW_MMC_IDMAC_DES1_BS1 (Remaining + DWMMC_DMA_BUF_SIZE);
1190 // Set the next field of the Last Descriptor
1191 Trb->DmaDesc[Entries - 1].Des3 = 0;
1192 DmaDescPhy = (UINT32)Trb->DmaDescPhy;
1193 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_DBADDR, FALSE, sizeof (DmaDescPhy), &DmaDescPhy);
1194 if (EFI_ERROR (Status)) {
1195 return Status;
1196 }
1197 ArmDataSynchronizationBarrier ();
1198 ArmInstructionSynchronizationBarrier ();
1199 // Clear interrupts
1200 Idsts = ~0;
1201 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_IDSTS, FALSE, sizeof (Idsts), &Idsts);
1202 return Status;
1203 }
1204
1205 EFI_STATUS
ReadFifo(IN DW_MMC_HC_TRB * Trb)1206 ReadFifo (
1207 IN DW_MMC_HC_TRB *Trb
1208 )
1209 {
1210 EFI_STATUS Status;
1211 EFI_PCI_IO_PROTOCOL *PciIo;
1212 UINT32 Data;
1213 UINT32 Received;
1214 UINT32 Count;
1215 UINT32 Intsts;
1216 UINT32 Sts;
1217 UINT32 FifoCount;
1218 UINT32 Index; // count with bytes
1219 UINT32 Ascending;
1220 UINT32 Descending;
1221
1222 PciIo = Trb->Private->PciIo;
1223 Received = 0;
1224 Count = 0;
1225 Index = 0;
1226 Ascending = 0;
1227 Descending = ((Trb->DataLen + 3) & ~3) - 4;
1228 do {
1229 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, TRUE, sizeof (Intsts), &Intsts);
1230 if (EFI_ERROR (Status)) {
1231 DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read RINTSTS, Status:%r\n", Status));
1232 return Status;
1233 }
1234 if (Trb->DataLen && ((Intsts & DW_MMC_INT_RXDR) || (Intsts & DW_MMC_INT_DTO))) {
1235 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_STATUS, TRUE, sizeof (Sts), &Sts);
1236 if (EFI_ERROR (Status)) {
1237 DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read STATUS, Status:%r\n", Status));
1238 return Status;
1239 }
1240 // Convert to bytes
1241 FifoCount = GET_STS_FIFO_COUNT (Sts) << 2;
1242 if ((FifoCount == 0) && (Received < Trb->DataLen)) {
1243 continue;
1244 }
1245 Index = 0;
1246 Count = (MIN (FifoCount, Trb->DataLen) + 3) & ~3;
1247 while (Index < Count) {
1248 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_FIFO_START, TRUE, sizeof (Data), &Data);
1249 if (EFI_ERROR (Status)) {
1250 DEBUG ((DEBUG_ERROR, "ReadFifo: failed to read FIFO, Status:%r\n", Status));
1251 return Status;
1252 }
1253 if (Trb->UseBE) {
1254 *(UINT32 *)((UINTN)Trb->Data + Descending) = SwapBytes32 (Data);
1255 Descending = Descending - 4;
1256 } else {
1257 *(UINT32 *)((UINTN)Trb->Data + Ascending) = Data;
1258 Ascending += 4;
1259 }
1260 Index += 4;
1261 Received += 4;
1262 } // while
1263 } // if
1264 } while (((Intsts & DW_MMC_INT_CMD_DONE) == 0) || (Received < Trb->DataLen));
1265 // Clear RINTSTS
1266 Intsts = ~0;
1267 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, FALSE, sizeof (Intsts), &Intsts);
1268 if (EFI_ERROR (Status)) {
1269 DEBUG ((DEBUG_ERROR, "ReadFifo: failed to write RINTSTS, Status:%r\n", Status));
1270 return Status;
1271 }
1272 return EFI_SUCCESS;
1273 }
1274
1275 /**
1276 Create a new TRB for the SD/MMC cmd request.
1277
1278 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1279 @param[in] Slot The slot number of the SD card to send the command to.
1280 @param[in] Packet A pointer to the SD command data structure.
1281 @param[in] Event If Event is NULL, blocking I/O is performed. If Event is
1282 not NULL, then nonblocking I/O is performed, and Event
1283 will be signaled when the Packet completes.
1284
1285 @return Created Trb or NULL.
1286
1287 **/
1288 DW_MMC_HC_TRB *
DwMmcCreateTrb(IN DW_MMC_HC_PRIVATE_DATA * Private,IN UINT8 Slot,IN EFI_SD_MMC_PASS_THRU_COMMAND_PACKET * Packet,IN EFI_EVENT Event)1289 DwMmcCreateTrb (
1290 IN DW_MMC_HC_PRIVATE_DATA *Private,
1291 IN UINT8 Slot,
1292 IN EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet,
1293 IN EFI_EVENT Event
1294 )
1295 {
1296 DW_MMC_HC_TRB *Trb;
1297 EFI_STATUS Status;
1298 EFI_TPL OldTpl;
1299 EFI_PCI_IO_PROTOCOL_OPERATION Flag;
1300 EFI_PCI_IO_PROTOCOL *PciIo;
1301 UINTN MapLength;
1302
1303 Trb = AllocateZeroPool (sizeof (DW_MMC_HC_TRB));
1304 if (Trb == NULL) {
1305 return NULL;
1306 }
1307
1308 Trb->Signature = DW_MMC_HC_TRB_SIG;
1309 Trb->Slot = Slot;
1310 Trb->BlockSize = 0x200;
1311 Trb->Packet = Packet;
1312 Trb->Event = Event;
1313 Trb->Started = FALSE;
1314 Trb->Timeout = Packet->Timeout;
1315 Trb->Private = Private;
1316
1317 if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) {
1318 Trb->Data = Packet->InDataBuffer;
1319 Trb->DataLen = Packet->InTransferLength;
1320 Trb->Read = TRUE;
1321 ZeroMem (Trb->Data, Trb->DataLen);
1322 } else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer != NULL)) {
1323 Trb->Data = Packet->OutDataBuffer;
1324 Trb->DataLen = Packet->OutTransferLength;
1325 Trb->Read = FALSE;
1326 } else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) {
1327 Trb->Data = NULL;
1328 Trb->DataLen = 0;
1329 } else {
1330 goto Error;
1331 }
1332
1333 if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&
1334 (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||
1335 ((Private->Slot[Trb->Slot].CardType == SdCardType) &&
1336 (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {
1337 Trb->Mode = SdMmcPioMode;
1338 } else {
1339 if (Trb->Read) {
1340 Flag = EfiPciIoOperationBusMasterWrite;
1341 } else {
1342 Flag = EfiPciIoOperationBusMasterRead;
1343 }
1344
1345 PciIo = Private->PciIo;
1346 #if 0
1347 if ((Private->Slot[Trb->Slot].CardType == SdCardType) &&
1348 (Trb->DataLen != 0) &&
1349 (Trb->DataLen <= DWMMC_FIFO_THRESHOLD)) {
1350 #else
1351 if (Private->Slot[Trb->Slot].CardType == SdCardType) {
1352 #endif
1353 Trb->UseFifo = TRUE;
1354 } else {
1355 Trb->UseFifo = FALSE;
1356 if (Trb->DataLen) {
1357 MapLength = Trb->DataLen;
1358 Status = PciIo->Map (
1359 PciIo,
1360 Flag,
1361 Trb->Data,
1362 &MapLength,
1363 &Trb->DataPhy,
1364 &Trb->DataMap
1365 );
1366 if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {
1367 Status = EFI_BAD_BUFFER_SIZE;
1368 goto Error;
1369 }
1370
1371 Status = BuildDmaDescTable (Trb);
1372 if (EFI_ERROR (Status)) {
1373 PciIo->Unmap (PciIo, Trb->DataMap);
1374 goto Error;
1375 }
1376 Status = DwMmcHcStartDma (Private, Trb);
1377 if (EFI_ERROR (Status)) {
1378 PciIo->Unmap (PciIo, Trb->DataMap);
1379 goto Error;
1380 }
1381 }
1382 }
1383 } // TuningBlock
1384
1385 if (Event != NULL) {
1386 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
1387 InsertTailList (&Private->Queue, &Trb->TrbList);
1388 gBS->RestoreTPL (OldTpl);
1389 }
1390
1391 return Trb;
1392
1393 Error:
1394 //DwMmcFreeTrb (Trb);
1395 return NULL;
1396 }
1397
1398 /**
1399 Free the resource used by the TRB.
1400
1401 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1402
1403 **/
1404 VOID
1405 DwMmcFreeTrb (
1406 IN DW_MMC_HC_TRB *Trb
1407 )
1408 {
1409 EFI_PCI_IO_PROTOCOL *PciIo;
1410
1411 PciIo = Trb->Private->PciIo;
1412
1413 if (Trb->DmaMap != NULL) {
1414 PciIo->Unmap (
1415 PciIo,
1416 Trb->DmaMap
1417 );
1418 }
1419 #if 0
1420 // Free is handled in Unmap().
1421 if (Trb->DmaDesc != NULL) {
1422 PciIo->FreeBuffer (
1423 PciIo,
1424 Trb->DmaDescPages,
1425 Trb->DmaDesc
1426 );
1427 }
1428 #endif
1429 if (Trb->DataMap != NULL) {
1430 PciIo->Unmap (
1431 PciIo,
1432 Trb->DataMap
1433 );
1434 }
1435 FreePool (Trb);
1436 return;
1437 }
1438
1439 /**
1440 Check if the env is ready for execute specified TRB.
1441
1442 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1443 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1444
1445 @retval EFI_SUCCESS The env is ready for TRB execution.
1446 @retval EFI_NOT_READY The env is not ready for TRB execution.
1447 @retval Others Some erros happen.
1448
1449 **/
1450 EFI_STATUS
1451 DwMmcCheckTrbEnv (
1452 IN DW_MMC_HC_PRIVATE_DATA *Private,
1453 IN DW_MMC_HC_TRB *Trb
1454 )
1455 {
1456 return EFI_SUCCESS;
1457 }
1458
1459 /**
1460 Wait for the env to be ready for execute specified TRB.
1461
1462 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1463 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1464
1465 @retval EFI_SUCCESS The env is ready for TRB execution.
1466 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.
1467 @retval Others Some erros happen.
1468
1469 **/
1470 EFI_STATUS
1471 DwMmcWaitTrbEnv (
1472 IN DW_MMC_HC_PRIVATE_DATA *Private,
1473 IN DW_MMC_HC_TRB *Trb
1474 )
1475 {
1476 EFI_STATUS Status;
1477 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;
1478 UINT64 Timeout;
1479 BOOLEAN InfiniteWait;
1480
1481 //
1482 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1483 //
1484 Packet = Trb->Packet;
1485 Timeout = Packet->Timeout;
1486 if (Timeout == 0) {
1487 InfiniteWait = TRUE;
1488 } else {
1489 InfiniteWait = FALSE;
1490 }
1491
1492 while (InfiniteWait || (Timeout > 0)) {
1493 //
1494 // Check Trb execution result by reading Normal Interrupt Status register.
1495 //
1496 Status = DwMmcCheckTrbEnv (Private, Trb);
1497 if (Status != EFI_NOT_READY) {
1498 return Status;
1499 }
1500 //
1501 // Stall for 1 microsecond.
1502 //
1503 gBS->Stall (1);
1504
1505 Timeout--;
1506 }
1507
1508 return EFI_TIMEOUT;
1509 }
1510
1511 EFI_STATUS
1512 DwEmmcExecTrb (
1513 IN DW_MMC_HC_PRIVATE_DATA *Private,
1514 IN DW_MMC_HC_TRB *Trb
1515 )
1516 {
1517 EFI_STATUS Status;
1518 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;
1519 EFI_PCI_IO_PROTOCOL *PciIo;
1520 UINT32 Cmd;
1521 UINT32 MmcStatus;
1522 UINT32 IntStatus;
1523 UINT32 Argument;
1524 UINT32 ErrMask;
1525 UINT32 Timeout;
1526
1527 Packet = Trb->Packet;
1528 PciIo = Trb->Private->PciIo;
1529
1530 ArmDataSynchronizationBarrier ();
1531 ArmInstructionSynchronizationBarrier ();
1532 // Wait until MMC is idle
1533 do {
1534 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_STATUS, TRUE, sizeof (MmcStatus), &MmcStatus);
1535 if (EFI_ERROR (Status)) {
1536 return Status;
1537 }
1538 } while (MmcStatus & DW_MMC_STS_DATA_BUSY);
1539
1540 IntStatus = ~0;
1541 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, FALSE, sizeof (IntStatus), &IntStatus);
1542 if (EFI_ERROR (Status)) {
1543 return Status;
1544 }
1545 Cmd = CMD_INDEX (Packet->SdMmcCmdBlk->CommandIndex);
1546 if ((Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAc) ||
1547 (Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc)) {
1548 switch (Packet->SdMmcCmdBlk->CommandIndex) {
1549 case EMMC_SET_RELATIVE_ADDR:
1550 Cmd |= BIT_CMD_SEND_INIT;
1551 break;
1552 case EMMC_SEND_STATUS:
1553 Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE;
1554 break;
1555 case EMMC_STOP_TRANSMISSION:
1556 Cmd |= BIT_CMD_STOP_ABORT_CMD;
1557 break;
1558 }
1559 if (Packet->InTransferLength) {
1560 Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_DATA_EXPECTED | BIT_CMD_READ;
1561 } else if (Packet->OutTransferLength) {
1562 Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_DATA_EXPECTED | BIT_CMD_WRITE;
1563 }
1564 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
1565 } else {
1566 switch (Packet->SdMmcCmdBlk->CommandIndex) {
1567 case EMMC_GO_IDLE_STATE:
1568 Cmd |= BIT_CMD_SEND_INIT;
1569 break;
1570 case EMMC_SEND_OP_COND:
1571 Cmd |= BIT_CMD_RESPONSE_EXPECT;
1572 break;
1573 case EMMC_ALL_SEND_CID:
1574 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_LONG_RESPONSE |
1575 BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_SEND_INIT;
1576 break;
1577 }
1578 }
1579 switch (Packet->SdMmcCmdBlk->ResponseType) {
1580 case SdMmcResponseTypeR2:
1581 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_LONG_RESPONSE;
1582 break;
1583 case SdMmcResponseTypeR3:
1584 Cmd |= BIT_CMD_RESPONSE_EXPECT;
1585 break;
1586 }
1587 Cmd |= BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
1588
1589 Argument = Packet->SdMmcCmdBlk->CommandArgument;
1590 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CMDARG, FALSE, sizeof (Argument), &Argument);
1591 if (EFI_ERROR (Status)) {
1592 return Status;
1593 }
1594 ArmDataSynchronizationBarrier ();
1595 ArmInstructionSynchronizationBarrier ();
1596 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CMD, FALSE, sizeof (Cmd), &Cmd);
1597 if (EFI_ERROR (Status)) {
1598 return Status;
1599 }
1600 ArmDataSynchronizationBarrier ();
1601 ArmInstructionSynchronizationBarrier ();
1602
1603 ErrMask = DW_MMC_INT_EBE | DW_MMC_INT_HLE | DW_MMC_INT_RTO |
1604 DW_MMC_INT_RCRC | DW_MMC_INT_RE;
1605 ErrMask |= DW_MMC_INT_DCRC | DW_MMC_INT_DRT | DW_MMC_INT_SBE;
1606 do {
1607 Timeout = 10000;
1608 if (--Timeout == 0) {
1609 break;
1610 }
1611 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, TRUE, sizeof (IntStatus), &IntStatus);
1612 if (EFI_ERROR (Status)) {
1613 return Status;
1614 }
1615 if (IntStatus & ErrMask) {
1616 return EFI_DEVICE_ERROR;
1617 }
1618 if (Trb->DataLen && ((IntStatus & DW_MMC_INT_DTO) == 0)) {
1619 // Transfer Not Done
1620 MicroSecondDelay (10);
1621 continue;
1622 }
1623 MicroSecondDelay (10);
1624 } while (!(IntStatus & DW_MMC_INT_CMD_DONE));
1625 switch (Packet->SdMmcCmdBlk->ResponseType) {
1626 case SdMmcResponseTypeR1:
1627 case SdMmcResponseTypeR1b:
1628 case SdMmcResponseTypeR3:
1629 case SdMmcResponseTypeR4:
1630 case SdMmcResponseTypeR5:
1631 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP0, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp0), &Packet->SdMmcStatusBlk->Resp0);
1632 if (EFI_ERROR (Status)) {
1633 return Status;
1634 }
1635 break;
1636 case SdMmcResponseTypeR2:
1637 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP0, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp0), &Packet->SdMmcStatusBlk->Resp0);
1638 if (EFI_ERROR (Status)) {
1639 return Status;
1640 }
1641 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP1, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp1), &Packet->SdMmcStatusBlk->Resp1);
1642 if (EFI_ERROR (Status)) {
1643 return Status;
1644 }
1645 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP2, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp2), &Packet->SdMmcStatusBlk->Resp2);
1646 if (EFI_ERROR (Status)) {
1647 return Status;
1648 }
1649 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP3, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp3), &Packet->SdMmcStatusBlk->Resp3);
1650 if (EFI_ERROR (Status)) {
1651 return Status;
1652 }
1653 break;
1654 }
1655
1656 //
1657 // The workaround on EMMC_SEND_CSD is used to be compatible with SDHC.
1658 //
1659 if (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_CSD) {
1660 {
1661 UINT32 Buf[4];
1662 ZeroMem (Buf, sizeof (Buf));
1663 CopyMem ((UINT8 *)Buf, (UINT8 *)&Packet->SdMmcStatusBlk->Resp0 + 1, sizeof (Buf) - 1);
1664 CopyMem ((UINT8 *)&Packet->SdMmcStatusBlk->Resp0, (UINT8 *)Buf, sizeof (Buf) - 1);
1665 }
1666 }
1667
1668 return EFI_SUCCESS;
1669 }
1670
1671 EFI_STATUS
1672 DwSdExecTrb (
1673 IN DW_MMC_HC_PRIVATE_DATA *Private,
1674 IN DW_MMC_HC_TRB *Trb
1675 )
1676 {
1677 EFI_STATUS Status;
1678 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;
1679 EFI_PCI_IO_PROTOCOL *PciIo;
1680 UINT32 Cmd;
1681 UINT32 MmcStatus;
1682 UINT32 IntStatus;
1683 UINT32 Argument;
1684 UINT32 ErrMask;
1685 UINT32 Timeout;
1686 UINT32 Idsts;
1687 UINT32 BytCnt;
1688 UINT32 BlkSize;
1689
1690 Packet = Trb->Packet;
1691 PciIo = Trb->Private->PciIo;
1692
1693 ArmDataSynchronizationBarrier ();
1694 ArmInstructionSynchronizationBarrier ();
1695 // Wait until MMC is idle
1696 do {
1697 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_STATUS, TRUE, sizeof (MmcStatus), &MmcStatus);
1698 if (EFI_ERROR (Status)) {
1699 return Status;
1700 }
1701 } while (MmcStatus & DW_MMC_STS_DATA_BUSY);
1702
1703 IntStatus = ~0;
1704 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, FALSE, sizeof (IntStatus), &IntStatus);
1705 if (EFI_ERROR (Status)) {
1706 return Status;
1707 }
1708 Cmd = CMD_INDEX (Packet->SdMmcCmdBlk->CommandIndex);
1709 if ((Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAc) ||
1710 (Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc)) {
1711 switch (Packet->SdMmcCmdBlk->CommandIndex) {
1712 case SD_SET_RELATIVE_ADDR:
1713 Cmd |= BIT_CMD_SEND_INIT;
1714 break;
1715 case SD_STOP_TRANSMISSION:
1716 Cmd |= BIT_CMD_STOP_ABORT_CMD;
1717 break;
1718 case SD_SEND_SCR:
1719 Trb->UseBE = TRUE;
1720 break;
1721 }
1722 if (Packet->InTransferLength) {
1723 Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_DATA_EXPECTED | BIT_CMD_READ;
1724 } else if (Packet->OutTransferLength) {
1725 Cmd |= BIT_CMD_WAIT_PRVDATA_COMPLETE | BIT_CMD_DATA_EXPECTED | BIT_CMD_WRITE;
1726 }
1727 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
1728 } else {
1729 switch (Packet->SdMmcCmdBlk->CommandIndex) {
1730 case SD_GO_IDLE_STATE:
1731 Cmd |= BIT_CMD_SEND_INIT;
1732 break;
1733 }
1734 }
1735 switch (Packet->SdMmcCmdBlk->ResponseType) {
1736 case SdMmcResponseTypeR2:
1737 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC | BIT_CMD_LONG_RESPONSE;
1738 break;
1739 case SdMmcResponseTypeR3:
1740 Cmd |= BIT_CMD_RESPONSE_EXPECT;
1741 break;
1742 case SdMmcResponseTypeR1b:
1743 case SdMmcResponseTypeR4:
1744 case SdMmcResponseTypeR6:
1745 case SdMmcResponseTypeR7:
1746 Cmd |= BIT_CMD_RESPONSE_EXPECT | BIT_CMD_CHECK_RESPONSE_CRC;
1747 break;
1748 }
1749 Cmd |= BIT_CMD_USE_HOLD_REG | BIT_CMD_START;
1750
1751 if (Trb->UseFifo == TRUE) {
1752 BytCnt = Packet->InTransferLength;
1753 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BYTCNT, FALSE, sizeof (BytCnt), &BytCnt);
1754 if (EFI_ERROR (Status)) {
1755 return Status;
1756 }
1757 if (Packet->InTransferLength > DW_MMC_BLOCK_SIZE) {
1758 BlkSize = DW_MMC_BLOCK_SIZE;
1759 } else {
1760 BlkSize = Packet->InTransferLength;
1761 }
1762 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_BLKSIZ, FALSE, sizeof (BlkSize), &BlkSize);
1763 if (EFI_ERROR (Status)) {
1764 DEBUG ((DEBUG_ERROR, "DwMmcHcReset: set block size fails: %r\n", Status));
1765 return Status;
1766 }
1767 }
1768
1769 Argument = Packet->SdMmcCmdBlk->CommandArgument;
1770 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CMDARG, FALSE, sizeof (Argument), &Argument);
1771 if (EFI_ERROR (Status)) {
1772 return Status;
1773 }
1774 ArmDataSynchronizationBarrier ();
1775 ArmInstructionSynchronizationBarrier ();
1776 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_CMD, FALSE, sizeof (Cmd), &Cmd);
1777 if (EFI_ERROR (Status)) {
1778 return Status;
1779 }
1780 ArmDataSynchronizationBarrier ();
1781 ArmInstructionSynchronizationBarrier ();
1782
1783 ErrMask = DW_MMC_INT_EBE | DW_MMC_INT_HLE | DW_MMC_INT_RTO |
1784 DW_MMC_INT_RCRC | DW_MMC_INT_RE;
1785 ErrMask |= DW_MMC_INT_DRT | DW_MMC_INT_SBE;
1786 if (Packet->InTransferLength || Packet->OutTransferLength) {
1787 ErrMask |= DW_MMC_INT_DCRC;
1788 }
1789 if (Trb->UseFifo == TRUE) {
1790 Status = ReadFifo (Trb);
1791 if (EFI_ERROR (Status)) {
1792 return Status;
1793 }
1794 } else {
1795 Timeout = 10000;
1796 do {
1797 if (--Timeout == 0) {
1798 break;
1799 }
1800 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RINTSTS, TRUE, sizeof (IntStatus), &IntStatus);
1801 if (EFI_ERROR (Status)) {
1802 return Status;
1803 }
1804 if (IntStatus & ErrMask) {
1805 return EFI_DEVICE_ERROR;
1806 }
1807 if (Trb->DataLen && ((IntStatus & DW_MMC_INT_DTO) == 0)) {
1808 // Transfer not Done
1809 MicroSecondDelay (10);
1810 continue;
1811 }
1812 MicroSecondDelay (10);
1813 } while (!(IntStatus & DW_MMC_INT_CMD_DONE));
1814 if (Packet->InTransferLength) {
1815 do {
1816 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_IDSTS, TRUE, sizeof (Idsts), &Idsts);
1817 if (EFI_ERROR (Status)) {
1818 return Status;
1819 }
1820 } while ((Idsts & DW_MMC_IDSTS_RI) == 0);
1821 Status = DwMmcHcStopDma (Private, Trb);
1822 if (EFI_ERROR (Status)) {
1823 return Status;
1824 }
1825 } else if (Packet->OutTransferLength) {
1826 do {
1827 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_IDSTS, TRUE, sizeof (Idsts), &Idsts);
1828 if (EFI_ERROR (Status)) {
1829 return Status;
1830 }
1831 } while ((Idsts & DW_MMC_IDSTS_TI) == 0);
1832 Status = DwMmcHcStopDma (Private, Trb);
1833 if (EFI_ERROR (Status)) {
1834 return Status;
1835 }
1836 } // Packet->InTransferLength
1837 } // UseFifo
1838 switch (Packet->SdMmcCmdBlk->ResponseType) {
1839 case SdMmcResponseTypeR1:
1840 case SdMmcResponseTypeR1b:
1841 case SdMmcResponseTypeR3:
1842 case SdMmcResponseTypeR4:
1843 case SdMmcResponseTypeR5:
1844 case SdMmcResponseTypeR6:
1845 case SdMmcResponseTypeR7:
1846 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP0, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp0), &Packet->SdMmcStatusBlk->Resp0);
1847 if (EFI_ERROR (Status)) {
1848 return Status;
1849 }
1850 break;
1851 case SdMmcResponseTypeR2:
1852 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP0, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp0), &Packet->SdMmcStatusBlk->Resp0);
1853 if (EFI_ERROR (Status)) {
1854 return Status;
1855 }
1856 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP1, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp1), &Packet->SdMmcStatusBlk->Resp1);
1857 if (EFI_ERROR (Status)) {
1858 return Status;
1859 }
1860 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP2, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp2), &Packet->SdMmcStatusBlk->Resp2);
1861 if (EFI_ERROR (Status)) {
1862 return Status;
1863 }
1864 Status = DwMmcHcRwMmio (PciIo, Trb->Slot, DW_MMC_RESP3, TRUE, sizeof (Packet->SdMmcStatusBlk->Resp3), &Packet->SdMmcStatusBlk->Resp3);
1865 if (EFI_ERROR (Status)) {
1866 return Status;
1867 }
1868 break;
1869 }
1870
1871 //
1872 // The workaround on SD_SEND_CSD is used to be compatible with SDHC.
1873 //
1874 if (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_CSD) {
1875 {
1876 UINT32 Buf[4];
1877 ZeroMem (Buf, sizeof (Buf));
1878 CopyMem ((UINT8 *)Buf, (UINT8 *)&Packet->SdMmcStatusBlk->Resp0 + 1, sizeof (Buf) - 1);
1879 CopyMem ((UINT8 *)&Packet->SdMmcStatusBlk->Resp0, (UINT8 *)Buf, sizeof (Buf) - 1);
1880 }
1881 }
1882
1883 return EFI_SUCCESS;
1884 }
1885
1886 /**
1887 Execute the specified TRB.
1888
1889 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1890 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1891
1892 @retval EFI_SUCCESS The TRB is sent to host controller successfully.
1893 @retval Others Some erros happen when sending this request to the host controller.
1894
1895 **/
1896 EFI_STATUS
1897 DwMmcExecTrb (
1898 IN DW_MMC_HC_PRIVATE_DATA *Private,
1899 IN DW_MMC_HC_TRB *Trb
1900 )
1901 {
1902 EFI_STATUS Status = EFI_SUCCESS;
1903 UINT32 Slot;
1904
1905 Slot = Trb->Slot;
1906 if (Private->Slot[Slot].CardType == EmmcCardType) {
1907 Status = DwEmmcExecTrb (Private, Trb);
1908 } else if (Private->Slot[Slot].CardType == SdCardType) {
1909 Status = DwSdExecTrb (Private, Trb);
1910 } else {
1911 ASSERT (0);
1912 }
1913 return Status;
1914 }
1915
1916 /**
1917 Check the TRB execution result.
1918
1919 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1920 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1921
1922 @retval EFI_SUCCESS The TRB is executed successfully.
1923 @retval EFI_NOT_READY The TRB is not completed for execution.
1924 @retval Others Some erros happen when executing this request.
1925
1926 **/
1927 EFI_STATUS
1928 DwMmcCheckTrbResult (
1929 IN DW_MMC_HC_PRIVATE_DATA *Private,
1930 IN DW_MMC_HC_TRB *Trb
1931 )
1932 {
1933 EFI_STATUS Status;
1934 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;
1935 UINT32 Idsts;
1936
1937 Packet = Trb->Packet;
1938 if (Trb->UseFifo == TRUE) {
1939 return EFI_SUCCESS;
1940 }
1941 if (Packet->InTransferLength) {
1942 do {
1943 Status = DwMmcHcRwMmio (Private->PciIo, Trb->Slot, DW_MMC_IDSTS, TRUE, sizeof (Idsts), &Idsts);
1944 if (EFI_ERROR (Status)) {
1945 return Status;
1946 }
1947 } while ((Idsts & BIT1) == 0);
1948 } else if (Packet->OutTransferLength) {
1949 do {
1950 Status = DwMmcHcRwMmio (Private->PciIo, Trb->Slot, DW_MMC_IDSTS, TRUE, sizeof (Idsts), &Idsts);
1951 if (EFI_ERROR (Status)) {
1952 return Status;
1953 }
1954 } while ((Idsts & BIT0) == 0);
1955 } else {
1956 return EFI_SUCCESS;
1957 }
1958 Idsts = ~0;
1959 Status = DwMmcHcRwMmio (Private->PciIo, Trb->Slot, DW_MMC_IDSTS, FALSE, sizeof (Idsts), &Idsts);
1960 if (EFI_ERROR (Status)) {
1961 return Status;
1962 }
1963 return EFI_SUCCESS;
1964 }
1965
1966 /**
1967 Wait for the TRB execution result.
1968
1969 @param[in] Private A pointer to the DW_MMC_HC_PRIVATE_DATA instance.
1970 @param[in] Trb The pointer to the DW_MMC_HC_TRB instance.
1971
1972 @retval EFI_SUCCESS The TRB is executed successfully.
1973 @retval Others Some erros happen when executing this request.
1974
1975 **/
1976 EFI_STATUS
1977 DwMmcWaitTrbResult (
1978 IN DW_MMC_HC_PRIVATE_DATA *Private,
1979 IN DW_MMC_HC_TRB *Trb
1980 )
1981 {
1982 EFI_STATUS Status;
1983 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;
1984 UINT64 Timeout;
1985 BOOLEAN InfiniteWait;
1986
1987 Packet = Trb->Packet;
1988 //
1989 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register
1990 //
1991 Timeout = Packet->Timeout;
1992 if (Timeout == 0) {
1993 InfiniteWait = TRUE;
1994 } else {
1995 InfiniteWait = FALSE;
1996 }
1997
1998 while (InfiniteWait || (Timeout > 0)) {
1999 //
2000 // Check Trb execution result by reading Normal Interrupt Status register.
2001 //
2002 Status = DwMmcCheckTrbResult (Private, Trb);
2003 if (Status != EFI_NOT_READY) {
2004 return Status;
2005 }
2006 //
2007 // Stall for 1 microsecond.
2008 //
2009 gBS->Stall (1);
2010
2011 Timeout--;
2012 }
2013
2014 return EFI_TIMEOUT;
2015 }
2016