]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHci.c
MdeModulePkg/SdMmcPciHcDxe: Update comment for spec compliance status
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / SdMmcPciHcDxe / SdMmcPciHci.c
CommitLineData
48555339
FT
1/** @file\r
2 This driver is used to manage SD/MMC PCI host controllers which are compliance\r
48190274
HW
3 with SD Host Controller Simplified Specification version 3.00 plus the 64-bit\r
4 System Addressing support in SD Host Controller Simplified Specification version\r
5 4.20.\r
48555339
FT
6\r
7 It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.\r
8\r
b5547b9c 9 Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.\r
48190274 10 Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
48555339
FT
11 This program and the accompanying materials\r
12 are licensed and made available under the terms and conditions of the BSD License\r
13 which accompanies this distribution. The full text of the license may be found at\r
14 http://opensource.org/licenses/bsd-license.php\r
15\r
16 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
17 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
18\r
19**/\r
20\r
21#include "SdMmcPciHcDxe.h"\r
22\r
23/**\r
24 Dump the content of SD/MMC host controller's Capability Register.\r
25\r
26 @param[in] Slot The slot number of the SD card to send the command to.\r
27 @param[in] Capability The buffer to store the capability data.\r
28\r
29**/\r
30VOID\r
31DumpCapabilityReg (\r
32 IN UINT8 Slot,\r
33 IN SD_MMC_HC_SLOT_CAP *Capability\r
34 )\r
35{\r
36 //\r
37 // Dump Capability Data\r
38 //\r
e27ccaba
FT
39 DEBUG ((DEBUG_INFO, " == Slot [%d] Capability is 0x%x ==\n", Slot, Capability));\r
40 DEBUG ((DEBUG_INFO, " Timeout Clk Freq %d%a\n", Capability->TimeoutFreq, (Capability->TimeoutUnit) ? "MHz" : "KHz"));\r
41 DEBUG ((DEBUG_INFO, " Base Clk Freq %dMHz\n", Capability->BaseClkFreq));\r
42 DEBUG ((DEBUG_INFO, " Max Blk Len %dbytes\n", 512 * (1 << Capability->MaxBlkLen)));\r
43 DEBUG ((DEBUG_INFO, " 8-bit Support %a\n", Capability->BusWidth8 ? "TRUE" : "FALSE"));\r
44 DEBUG ((DEBUG_INFO, " ADMA2 Support %a\n", Capability->Adma2 ? "TRUE" : "FALSE"));\r
45 DEBUG ((DEBUG_INFO, " HighSpeed Support %a\n", Capability->HighSpeed ? "TRUE" : "FALSE"));\r
46 DEBUG ((DEBUG_INFO, " SDMA Support %a\n", Capability->Sdma ? "TRUE" : "FALSE"));\r
47 DEBUG ((DEBUG_INFO, " Suspend/Resume %a\n", Capability->SuspRes ? "TRUE" : "FALSE"));\r
48 DEBUG ((DEBUG_INFO, " Voltage 3.3 %a\n", Capability->Voltage33 ? "TRUE" : "FALSE"));\r
49 DEBUG ((DEBUG_INFO, " Voltage 3.0 %a\n", Capability->Voltage30 ? "TRUE" : "FALSE"));\r
50 DEBUG ((DEBUG_INFO, " Voltage 1.8 %a\n", Capability->Voltage18 ? "TRUE" : "FALSE"));\r
b5547b9c
AS
51 DEBUG ((DEBUG_INFO, " V4 64-bit Sys Bus %a\n", Capability->SysBus64V4 ? "TRUE" : "FALSE"));\r
52 DEBUG ((DEBUG_INFO, " V3 64-bit Sys Bus %a\n", Capability->SysBus64V3 ? "TRUE" : "FALSE"));\r
e27ccaba
FT
53 DEBUG ((DEBUG_INFO, " Async Interrupt %a\n", Capability->AsyncInt ? "TRUE" : "FALSE"));\r
54 DEBUG ((DEBUG_INFO, " SlotType "));\r
48555339 55 if (Capability->SlotType == 0x00) {\r
e27ccaba 56 DEBUG ((DEBUG_INFO, "%a\n", "Removable Slot"));\r
48555339 57 } else if (Capability->SlotType == 0x01) {\r
e27ccaba 58 DEBUG ((DEBUG_INFO, "%a\n", "Embedded Slot"));\r
48555339 59 } else if (Capability->SlotType == 0x02) {\r
e27ccaba 60 DEBUG ((DEBUG_INFO, "%a\n", "Shared Bus Slot"));\r
48555339 61 } else {\r
e27ccaba 62 DEBUG ((DEBUG_INFO, "%a\n", "Reserved"));\r
48555339 63 }\r
e27ccaba
FT
64 DEBUG ((DEBUG_INFO, " SDR50 Support %a\n", Capability->Sdr50 ? "TRUE" : "FALSE"));\r
65 DEBUG ((DEBUG_INFO, " SDR104 Support %a\n", Capability->Sdr104 ? "TRUE" : "FALSE"));\r
66 DEBUG ((DEBUG_INFO, " DDR50 Support %a\n", Capability->Ddr50 ? "TRUE" : "FALSE"));\r
67 DEBUG ((DEBUG_INFO, " Driver Type A %a\n", Capability->DriverTypeA ? "TRUE" : "FALSE"));\r
68 DEBUG ((DEBUG_INFO, " Driver Type C %a\n", Capability->DriverTypeC ? "TRUE" : "FALSE"));\r
69 DEBUG ((DEBUG_INFO, " Driver Type D %a\n", Capability->DriverTypeD ? "TRUE" : "FALSE"));\r
70 DEBUG ((DEBUG_INFO, " Driver Type 4 %a\n", Capability->DriverType4 ? "TRUE" : "FALSE"));\r
48555339 71 if (Capability->TimerCount == 0) {\r
e27ccaba 72 DEBUG ((DEBUG_INFO, " Retuning TimerCnt Disabled\n", 2 * (Capability->TimerCount - 1)));\r
48555339 73 } else {\r
e27ccaba 74 DEBUG ((DEBUG_INFO, " Retuning TimerCnt %dseconds\n", 2 * (Capability->TimerCount - 1)));\r
48555339 75 }\r
e27ccaba
FT
76 DEBUG ((DEBUG_INFO, " SDR50 Tuning %a\n", Capability->TuningSDR50 ? "TRUE" : "FALSE"));\r
77 DEBUG ((DEBUG_INFO, " Retuning Mode Mode %d\n", Capability->RetuningMod + 1));\r
78 DEBUG ((DEBUG_INFO, " Clock Multiplier M = %d\n", Capability->ClkMultiplier + 1));\r
79 DEBUG ((DEBUG_INFO, " HS 400 %a\n", Capability->Hs400 ? "TRUE" : "FALSE"));\r
48555339
FT
80 return;\r
81}\r
82\r
83/**\r
84 Read SlotInfo register from SD/MMC host controller pci config space.\r
85\r
86 @param[in] PciIo The PCI IO protocol instance.\r
87 @param[out] FirstBar The buffer to store the first BAR value.\r
88 @param[out] SlotNum The buffer to store the supported slot number.\r
89\r
90 @retval EFI_SUCCESS The operation succeeds.\r
91 @retval Others The operation fails.\r
92\r
93**/\r
94EFI_STATUS\r
95EFIAPI\r
96SdMmcHcGetSlotInfo (\r
97 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
98 OUT UINT8 *FirstBar,\r
99 OUT UINT8 *SlotNum\r
100 )\r
101{\r
102 EFI_STATUS Status;\r
103 SD_MMC_HC_SLOT_INFO SlotInfo;\r
104\r
105 Status = PciIo->Pci.Read (\r
106 PciIo,\r
107 EfiPciIoWidthUint8,\r
108 SD_MMC_HC_SLOT_OFFSET,\r
109 sizeof (SlotInfo),\r
110 &SlotInfo\r
111 );\r
112 if (EFI_ERROR (Status)) {\r
113 return Status;\r
114 }\r
115\r
116 *FirstBar = SlotInfo.FirstBar;\r
117 *SlotNum = SlotInfo.SlotNum + 1;\r
118 ASSERT ((*FirstBar + *SlotNum) < SD_MMC_HC_MAX_SLOT);\r
119 return EFI_SUCCESS;\r
120}\r
121\r
122/**\r
123 Read/Write specified SD/MMC host controller mmio register.\r
124\r
125 @param[in] PciIo The PCI IO protocol instance.\r
126 @param[in] BarIndex The BAR index of the standard PCI Configuration\r
127 header to use as the base address for the memory\r
128 operation to perform.\r
129 @param[in] Offset The offset within the selected BAR to start the\r
130 memory operation.\r
131 @param[in] Read A boolean to indicate it's read or write operation.\r
132 @param[in] Count The width of the mmio register in bytes.\r
133 Must be 1, 2 , 4 or 8 bytes.\r
134 @param[in, out] Data For read operations, the destination buffer to store\r
135 the results. For write operations, the source buffer\r
136 to write data from. The caller is responsible for\r
137 having ownership of the data buffer and ensuring its\r
138 size not less than Count bytes.\r
139\r
140 @retval EFI_INVALID_PARAMETER The PciIo or Data is NULL or the Count is not valid.\r
141 @retval EFI_SUCCESS The read/write operation succeeds.\r
142 @retval Others The read/write operation fails.\r
143\r
144**/\r
145EFI_STATUS\r
146EFIAPI\r
147SdMmcHcRwMmio (\r
148 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
149 IN UINT8 BarIndex,\r
150 IN UINT32 Offset,\r
151 IN BOOLEAN Read,\r
152 IN UINT8 Count,\r
153 IN OUT VOID *Data\r
154 )\r
155{\r
156 EFI_STATUS Status;\r
157\r
158 if ((PciIo == NULL) || (Data == NULL)) {\r
159 return EFI_INVALID_PARAMETER;\r
160 }\r
161\r
162 if ((Count != 1) && (Count != 2) && (Count != 4) && (Count != 8)) {\r
163 return EFI_INVALID_PARAMETER;\r
164 }\r
165\r
166 if (Read) {\r
167 Status = PciIo->Mem.Read (\r
168 PciIo,\r
169 EfiPciIoWidthUint8,\r
170 BarIndex,\r
171 (UINT64) Offset,\r
172 Count,\r
173 Data\r
174 );\r
175 } else {\r
176 Status = PciIo->Mem.Write (\r
177 PciIo,\r
178 EfiPciIoWidthUint8,\r
179 BarIndex,\r
180 (UINT64) Offset,\r
181 Count,\r
182 Data\r
183 );\r
184 }\r
185\r
186 return Status;\r
187}\r
188\r
189/**\r
190 Do OR operation with the value of the specified SD/MMC host controller mmio register.\r
191\r
192 @param[in] PciIo The PCI IO protocol instance.\r
193 @param[in] BarIndex The BAR index of the standard PCI Configuration\r
194 header to use as the base address for the memory\r
195 operation to perform.\r
196 @param[in] Offset The offset within the selected BAR to start the\r
197 memory operation.\r
198 @param[in] Count The width of the mmio register in bytes.\r
199 Must be 1, 2 , 4 or 8 bytes.\r
200 @param[in] OrData The pointer to the data used to do OR operation.\r
201 The caller is responsible for having ownership of\r
202 the data buffer and ensuring its size not less than\r
203 Count bytes.\r
204\r
205 @retval EFI_INVALID_PARAMETER The PciIo or OrData is NULL or the Count is not valid.\r
206 @retval EFI_SUCCESS The OR operation succeeds.\r
207 @retval Others The OR operation fails.\r
208\r
209**/\r
210EFI_STATUS\r
211EFIAPI\r
212SdMmcHcOrMmio (\r
213 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
214 IN UINT8 BarIndex,\r
215 IN UINT32 Offset,\r
216 IN UINT8 Count,\r
217 IN VOID *OrData\r
218 )\r
219{\r
220 EFI_STATUS Status;\r
221 UINT64 Data;\r
222 UINT64 Or;\r
223\r
224 Status = SdMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);\r
225 if (EFI_ERROR (Status)) {\r
226 return Status;\r
227 }\r
228\r
229 if (Count == 1) {\r
230 Or = *(UINT8*) OrData;\r
231 } else if (Count == 2) {\r
232 Or = *(UINT16*) OrData;\r
233 } else if (Count == 4) {\r
234 Or = *(UINT32*) OrData;\r
235 } else if (Count == 8) {\r
236 Or = *(UINT64*) OrData;\r
237 } else {\r
238 return EFI_INVALID_PARAMETER;\r
239 }\r
240\r
241 Data |= Or;\r
242 Status = SdMmcHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);\r
243\r
244 return Status;\r
245}\r
246\r
247/**\r
248 Do AND operation with the value of the specified SD/MMC host controller mmio register.\r
249\r
250 @param[in] PciIo The PCI IO protocol instance.\r
251 @param[in] BarIndex The BAR index of the standard PCI Configuration\r
252 header to use as the base address for the memory\r
253 operation to perform.\r
254 @param[in] Offset The offset within the selected BAR to start the\r
255 memory operation.\r
256 @param[in] Count The width of the mmio register in bytes.\r
257 Must be 1, 2 , 4 or 8 bytes.\r
258 @param[in] AndData The pointer to the data used to do AND operation.\r
259 The caller is responsible for having ownership of\r
260 the data buffer and ensuring its size not less than\r
261 Count bytes.\r
262\r
263 @retval EFI_INVALID_PARAMETER The PciIo or AndData is NULL or the Count is not valid.\r
264 @retval EFI_SUCCESS The AND operation succeeds.\r
265 @retval Others The AND operation fails.\r
266\r
267**/\r
268EFI_STATUS\r
269EFIAPI\r
270SdMmcHcAndMmio (\r
271 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
272 IN UINT8 BarIndex,\r
273 IN UINT32 Offset,\r
274 IN UINT8 Count,\r
275 IN VOID *AndData\r
276 )\r
277{\r
278 EFI_STATUS Status;\r
279 UINT64 Data;\r
280 UINT64 And;\r
281\r
282 Status = SdMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Data);\r
283 if (EFI_ERROR (Status)) {\r
284 return Status;\r
285 }\r
286\r
287 if (Count == 1) {\r
288 And = *(UINT8*) AndData;\r
289 } else if (Count == 2) {\r
290 And = *(UINT16*) AndData;\r
291 } else if (Count == 4) {\r
292 And = *(UINT32*) AndData;\r
293 } else if (Count == 8) {\r
294 And = *(UINT64*) AndData;\r
295 } else {\r
296 return EFI_INVALID_PARAMETER;\r
297 }\r
298\r
299 Data &= And;\r
300 Status = SdMmcHcRwMmio (PciIo, BarIndex, Offset, FALSE, Count, &Data);\r
301\r
302 return Status;\r
303}\r
304\r
305/**\r
306 Wait for the value of the specified MMIO register set to the test value.\r
307\r
308 @param[in] PciIo The PCI IO protocol instance.\r
309 @param[in] BarIndex The BAR index of the standard PCI Configuration\r
310 header to use as the base address for the memory\r
311 operation to perform.\r
312 @param[in] Offset The offset within the selected BAR to start the\r
313 memory operation.\r
314 @param[in] Count The width of the mmio register in bytes.\r
315 Must be 1, 2, 4 or 8 bytes.\r
316 @param[in] MaskValue The mask value of memory.\r
317 @param[in] TestValue The test value of memory.\r
318\r
319 @retval EFI_NOT_READY The MMIO register hasn't set to the expected value.\r
320 @retval EFI_SUCCESS The MMIO register has expected value.\r
321 @retval Others The MMIO operation fails.\r
322\r
323**/\r
324EFI_STATUS\r
325EFIAPI\r
326SdMmcHcCheckMmioSet (\r
327 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
328 IN UINT8 BarIndex,\r
329 IN UINT32 Offset,\r
330 IN UINT8 Count,\r
331 IN UINT64 MaskValue,\r
332 IN UINT64 TestValue\r
333 )\r
334{\r
335 EFI_STATUS Status;\r
336 UINT64 Value;\r
337\r
338 //\r
339 // Access PCI MMIO space to see if the value is the tested one.\r
340 //\r
341 Value = 0;\r
342 Status = SdMmcHcRwMmio (PciIo, BarIndex, Offset, TRUE, Count, &Value);\r
343 if (EFI_ERROR (Status)) {\r
344 return Status;\r
345 }\r
346\r
347 Value &= MaskValue;\r
348\r
349 if (Value == TestValue) {\r
350 return EFI_SUCCESS;\r
351 }\r
352\r
353 return EFI_NOT_READY;\r
354}\r
355\r
356/**\r
357 Wait for the value of the specified MMIO register set to the test value.\r
358\r
359 @param[in] PciIo The PCI IO protocol instance.\r
360 @param[in] BarIndex The BAR index of the standard PCI Configuration\r
361 header to use as the base address for the memory\r
362 operation to perform.\r
363 @param[in] Offset The offset within the selected BAR to start the\r
364 memory operation.\r
365 @param[in] Count The width of the mmio register in bytes.\r
366 Must be 1, 2, 4 or 8 bytes.\r
367 @param[in] MaskValue The mask value of memory.\r
368 @param[in] TestValue The test value of memory.\r
369 @param[in] Timeout The time out value for wait memory set, uses 1\r
370 microsecond as a unit.\r
371\r
372 @retval EFI_TIMEOUT The MMIO register hasn't expected value in timeout\r
373 range.\r
374 @retval EFI_SUCCESS The MMIO register has expected value.\r
375 @retval Others The MMIO operation fails.\r
376\r
377**/\r
378EFI_STATUS\r
379EFIAPI\r
380SdMmcHcWaitMmioSet (\r
381 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
382 IN UINT8 BarIndex,\r
383 IN UINT32 Offset,\r
384 IN UINT8 Count,\r
385 IN UINT64 MaskValue,\r
386 IN UINT64 TestValue,\r
387 IN UINT64 Timeout\r
388 )\r
389{\r
390 EFI_STATUS Status;\r
391 BOOLEAN InfiniteWait;\r
392\r
393 if (Timeout == 0) {\r
394 InfiniteWait = TRUE;\r
395 } else {\r
396 InfiniteWait = FALSE;\r
397 }\r
398\r
399 while (InfiniteWait || (Timeout > 0)) {\r
400 Status = SdMmcHcCheckMmioSet (\r
401 PciIo,\r
402 BarIndex,\r
403 Offset,\r
404 Count,\r
405 MaskValue,\r
406 TestValue\r
407 );\r
408 if (Status != EFI_NOT_READY) {\r
409 return Status;\r
410 }\r
411\r
412 //\r
413 // Stall for 1 microsecond.\r
414 //\r
415 gBS->Stall (1);\r
416\r
417 Timeout--;\r
418 }\r
419\r
420 return EFI_TIMEOUT;\r
421}\r
422\r
b5547b9c
AS
423/**\r
424 Get the controller version information from the specified slot.\r
425\r
426 @param[in] PciIo The PCI IO protocol instance.\r
427 @param[in] Slot The slot number of the SD card to send the command to.\r
428 @param[out] Version The buffer to store the version information.\r
429\r
430 @retval EFI_SUCCESS The operation executes successfully.\r
431 @retval Others The operation fails.\r
432\r
433**/\r
434EFI_STATUS\r
435SdMmcHcGetControllerVersion (\r
436 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
437 IN UINT8 Slot,\r
438 OUT UINT16 *Version\r
439 )\r
440{\r
441 EFI_STATUS Status;\r
442\r
443 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CTRL_VER, TRUE, sizeof (UINT16), Version);\r
444 if (EFI_ERROR (Status)) {\r
445 return Status;\r
446 }\r
447\r
448 *Version &= 0xFF;\r
449\r
450 return EFI_SUCCESS;\r
451}\r
452\r
48555339
FT
453/**\r
454 Software reset the specified SD/MMC host controller and enable all interrupts.\r
455\r
b23fc39c 456 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
48555339
FT
457 @param[in] Slot The slot number of the SD card to send the command to.\r
458\r
459 @retval EFI_SUCCESS The software reset executes successfully.\r
460 @retval Others The software reset fails.\r
461\r
462**/\r
463EFI_STATUS\r
464SdMmcHcReset (\r
b23fc39c 465 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
48555339
FT
466 IN UINT8 Slot\r
467 )\r
468{\r
469 EFI_STATUS Status;\r
470 UINT8 SwReset;\r
b23fc39c 471 EFI_PCI_IO_PROTOCOL *PciIo;\r
48555339 472\r
b23fc39c
AB
473 //\r
474 // Notify the SD/MMC override protocol that we are about to reset\r
475 // the SD/MMC host controller.\r
476 //\r
477 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
478 Status = mOverride->NotifyPhase (\r
479 Private->ControllerHandle,\r
480 Slot,\r
49c99534
MW
481 EdkiiSdMmcResetPre,\r
482 NULL);\r
b23fc39c
AB
483 if (EFI_ERROR (Status)) {\r
484 DEBUG ((DEBUG_WARN,\r
485 "%a: SD/MMC pre reset notifier callback failed - %r\n",\r
486 __FUNCTION__, Status));\r
487 return Status;\r
488 }\r
489 }\r
490\r
491 PciIo = Private->PciIo;\r
064d301f
TM
492 SwReset = BIT0;\r
493 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_SW_RST, sizeof (SwReset), &SwReset);\r
48555339
FT
494\r
495 if (EFI_ERROR (Status)) {\r
064d301f 496 DEBUG ((DEBUG_ERROR, "SdMmcHcReset: write SW Reset for All fails: %r\n", Status));\r
48555339
FT
497 return Status;\r
498 }\r
499\r
500 Status = SdMmcHcWaitMmioSet (\r
501 PciIo,\r
502 Slot,\r
503 SD_MMC_HC_SW_RST,\r
504 sizeof (SwReset),\r
064d301f 505 BIT0,\r
48555339
FT
506 0x00,\r
507 SD_MMC_HC_GENERIC_TIMEOUT\r
508 );\r
509 if (EFI_ERROR (Status)) {\r
e27ccaba 510 DEBUG ((DEBUG_INFO, "SdMmcHcReset: reset done with %r\n", Status));\r
48555339
FT
511 return Status;\r
512 }\r
b23fc39c 513\r
48555339
FT
514 //\r
515 // Enable all interrupt after reset all.\r
516 //\r
517 Status = SdMmcHcEnableInterrupt (PciIo, Slot);\r
b23fc39c
AB
518 if (EFI_ERROR (Status)) {\r
519 DEBUG ((DEBUG_INFO, "SdMmcHcReset: SdMmcHcEnableInterrupt done with %r\n",\r
520 Status));\r
521 return Status;\r
522 }\r
523\r
524 //\r
525 // Notify the SD/MMC override protocol that we have just reset\r
526 // the SD/MMC host controller.\r
527 //\r
528 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
529 Status = mOverride->NotifyPhase (\r
530 Private->ControllerHandle,\r
531 Slot,\r
49c99534
MW
532 EdkiiSdMmcResetPost,\r
533 NULL);\r
b23fc39c
AB
534 if (EFI_ERROR (Status)) {\r
535 DEBUG ((DEBUG_WARN,\r
536 "%a: SD/MMC post reset notifier callback failed - %r\n",\r
537 __FUNCTION__, Status));\r
538 }\r
539 }\r
48555339
FT
540\r
541 return Status;\r
542}\r
543\r
544/**\r
545 Set all interrupt status bits in Normal and Error Interrupt Status Enable\r
546 register.\r
547\r
548 @param[in] PciIo The PCI IO protocol instance.\r
549 @param[in] Slot The slot number of the SD card to send the command to.\r
550\r
551 @retval EFI_SUCCESS The operation executes successfully.\r
552 @retval Others The operation fails.\r
553\r
554**/\r
555EFI_STATUS\r
556SdMmcHcEnableInterrupt (\r
557 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
558 IN UINT8 Slot\r
559 )\r
560{\r
561 EFI_STATUS Status;\r
562 UINT16 IntStatus;\r
563\r
564 //\r
565 // Enable all bits in Error Interrupt Status Enable Register\r
566 //\r
567 IntStatus = 0xFFFF;\r
568 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_ERR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus);\r
569 if (EFI_ERROR (Status)) {\r
570 return Status;\r
571 }\r
572 //\r
573 // Enable all bits in Normal Interrupt Status Enable Register\r
574 //\r
575 IntStatus = 0xFFFF;\r
576 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_NOR_INT_STS_EN, FALSE, sizeof (IntStatus), &IntStatus);\r
577\r
578 return Status;\r
579}\r
580\r
581/**\r
582 Get the capability data from the specified slot.\r
583\r
584 @param[in] PciIo The PCI IO protocol instance.\r
585 @param[in] Slot The slot number of the SD card to send the command to.\r
586 @param[out] Capability The buffer to store the capability data.\r
587\r
588 @retval EFI_SUCCESS The operation executes successfully.\r
589 @retval Others The operation fails.\r
590\r
591**/\r
592EFI_STATUS\r
593SdMmcHcGetCapability (\r
594 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
595 IN UINT8 Slot,\r
596 OUT SD_MMC_HC_SLOT_CAP *Capability\r
597 )\r
598{\r
599 EFI_STATUS Status;\r
600 UINT64 Cap;\r
601\r
602 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CAP, TRUE, sizeof (Cap), &Cap);\r
603 if (EFI_ERROR (Status)) {\r
604 return Status;\r
605 }\r
606\r
607 CopyMem (Capability, &Cap, sizeof (Cap));\r
608\r
609 return EFI_SUCCESS;\r
610}\r
611\r
612/**\r
613 Get the maximum current capability data from the specified slot.\r
614\r
615 @param[in] PciIo The PCI IO protocol instance.\r
616 @param[in] Slot The slot number of the SD card to send the command to.\r
617 @param[out] MaxCurrent The buffer to store the maximum current capability data.\r
618\r
619 @retval EFI_SUCCESS The operation executes successfully.\r
620 @retval Others The operation fails.\r
621\r
622**/\r
623EFI_STATUS\r
624SdMmcHcGetMaxCurrent (\r
625 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
626 IN UINT8 Slot,\r
627 OUT UINT64 *MaxCurrent\r
628 )\r
629{\r
630 EFI_STATUS Status;\r
631\r
632 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_MAX_CURRENT_CAP, TRUE, sizeof (UINT64), MaxCurrent);\r
633\r
634 return Status;\r
635}\r
636\r
637/**\r
638 Detect whether there is a SD/MMC card attached at the specified SD/MMC host controller\r
639 slot.\r
640\r
641 Refer to SD Host Controller Simplified spec 3.0 Section 3.1 for details.\r
642\r
643 @param[in] PciIo The PCI IO protocol instance.\r
644 @param[in] Slot The slot number of the SD card to send the command to.\r
645 @param[out] MediaPresent The pointer to the media present boolean value.\r
646\r
647 @retval EFI_SUCCESS There is no media change happened.\r
648 @retval EFI_MEDIA_CHANGED There is media change happened.\r
649 @retval Others The detection fails.\r
650\r
651**/\r
652EFI_STATUS\r
653SdMmcHcCardDetect (\r
654 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
655 IN UINT8 Slot,\r
656 OUT BOOLEAN *MediaPresent\r
657 )\r
658{\r
659 EFI_STATUS Status;\r
660 UINT16 Data;\r
661 UINT32 PresentState;\r
662\r
2e9107b8
FT
663 //\r
664 // Check Present State Register to see if there is a card presented.\r
665 //\r
666 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_PRESENT_STATE, TRUE, sizeof (PresentState), &PresentState);\r
667 if (EFI_ERROR (Status)) {\r
668 return Status;\r
669 }\r
670\r
671 if ((PresentState & BIT16) != 0) {\r
672 *MediaPresent = TRUE;\r
673 } else {\r
674 *MediaPresent = FALSE;\r
675 }\r
676\r
48555339
FT
677 //\r
678 // Check Normal Interrupt Status Register\r
679 //\r
680 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_NOR_INT_STS, TRUE, sizeof (Data), &Data);\r
681 if (EFI_ERROR (Status)) {\r
682 return Status;\r
683 }\r
684\r
685 if ((Data & (BIT6 | BIT7)) != 0) {\r
686 //\r
687 // Clear BIT6 and BIT7 by writing 1 to these two bits if set.\r
688 //\r
689 Data &= BIT6 | BIT7;\r
690 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (Data), &Data);\r
691 if (EFI_ERROR (Status)) {\r
692 return Status;\r
693 }\r
694\r
48555339
FT
695 return EFI_MEDIA_CHANGED;\r
696 }\r
697\r
698 return EFI_SUCCESS;\r
699}\r
700\r
701/**\r
702 Stop SD/MMC card clock.\r
703\r
704 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.2 for details.\r
705\r
706 @param[in] PciIo The PCI IO protocol instance.\r
707 @param[in] Slot The slot number of the SD card to send the command to.\r
708\r
709 @retval EFI_SUCCESS Succeed to stop SD/MMC clock.\r
710 @retval Others Fail to stop SD/MMC clock.\r
711\r
712**/\r
713EFI_STATUS\r
714SdMmcHcStopClock (\r
715 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
716 IN UINT8 Slot\r
717 )\r
718{\r
719 EFI_STATUS Status;\r
720 UINT32 PresentState;\r
721 UINT16 ClockCtrl;\r
722\r
723 //\r
724 // Ensure no SD transactions are occurring on the SD Bus by\r
725 // waiting for Command Inhibit (DAT) and Command Inhibit (CMD)\r
726 // in the Present State register to be 0.\r
727 //\r
728 Status = SdMmcHcWaitMmioSet (\r
729 PciIo,\r
730 Slot,\r
731 SD_MMC_HC_PRESENT_STATE,\r
732 sizeof (PresentState),\r
733 BIT0 | BIT1,\r
734 0,\r
735 SD_MMC_HC_GENERIC_TIMEOUT\r
736 );\r
737 if (EFI_ERROR (Status)) {\r
738 return Status;\r
739 }\r
740\r
741 //\r
742 // Set SD Clock Enable in the Clock Control register to 0\r
743 //\r
744 ClockCtrl = (UINT16)~BIT2;\r
745 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);\r
746\r
747 return Status;\r
748}\r
749\r
750/**\r
751 SD/MMC card clock supply.\r
752\r
753 Refer to SD Host Controller Simplified spec 3.0 Section 3.2.1 for details.\r
754\r
755 @param[in] PciIo The PCI IO protocol instance.\r
756 @param[in] Slot The slot number of the SD card to send the command to.\r
757 @param[in] ClockFreq The max clock frequency to be set. The unit is KHz.\r
7f3b0bad 758 @param[in] BaseClkFreq The base clock frequency of host controller in MHz.\r
b5547b9c 759 @param[in] ControllerVer The version of host controller.\r
48555339
FT
760\r
761 @retval EFI_SUCCESS The clock is supplied successfully.\r
762 @retval Others The clock isn't supplied successfully.\r
763\r
764**/\r
765EFI_STATUS\r
766SdMmcHcClockSupply (\r
767 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
768 IN UINT8 Slot,\r
769 IN UINT64 ClockFreq,\r
b5547b9c
AS
770 IN UINT32 BaseClkFreq,\r
771 IN UINT16 ControllerVer\r
48555339
FT
772 )\r
773{\r
774 EFI_STATUS Status;\r
48555339
FT
775 UINT32 SettingFreq;\r
776 UINT32 Divisor;\r
777 UINT32 Remainder;\r
48555339
FT
778 UINT16 ClockCtrl;\r
779\r
780 //\r
781 // Calculate a divisor for SD clock frequency\r
782 //\r
7f3b0bad 783 ASSERT (BaseClkFreq != 0);\r
48555339 784\r
cb9cb9e2 785 if (ClockFreq == 0) {\r
48555339
FT
786 return EFI_INVALID_PARAMETER;\r
787 }\r
cb9cb9e2
FT
788\r
789 if (ClockFreq > (BaseClkFreq * 1000)) {\r
790 ClockFreq = BaseClkFreq * 1000;\r
791 }\r
792\r
48555339
FT
793 //\r
794 // Calculate the divisor of base frequency.\r
795 //\r
796 Divisor = 0;\r
797 SettingFreq = BaseClkFreq * 1000;\r
798 while (ClockFreq < SettingFreq) {\r
799 Divisor++;\r
800\r
801 SettingFreq = (BaseClkFreq * 1000) / (2 * Divisor);\r
802 Remainder = (BaseClkFreq * 1000) % (2 * Divisor);\r
803 if ((ClockFreq == SettingFreq) && (Remainder == 0)) {\r
804 break;\r
805 }\r
806 if ((ClockFreq == SettingFreq) && (Remainder != 0)) {\r
807 SettingFreq ++;\r
808 }\r
809 }\r
810\r
e27ccaba 811 DEBUG ((DEBUG_INFO, "BaseClkFreq %dMHz Divisor %d ClockFreq %dKhz\n", BaseClkFreq, Divisor, ClockFreq));\r
48555339 812\r
48555339
FT
813 //\r
814 // Set SDCLK Frequency Select and Internal Clock Enable fields in Clock Control register.\r
815 //\r
b5547b9c
AS
816 if ((ControllerVer >= SD_MMC_HC_CTRL_VER_300) &&\r
817 (ControllerVer <= SD_MMC_HC_CTRL_VER_420)) {\r
48555339
FT
818 ASSERT (Divisor <= 0x3FF);\r
819 ClockCtrl = ((Divisor & 0xFF) << 8) | ((Divisor & 0x300) >> 2);\r
b5547b9c
AS
820 } else if ((ControllerVer == SD_MMC_HC_CTRL_VER_100) ||\r
821 (ControllerVer == SD_MMC_HC_CTRL_VER_200)) {\r
48555339
FT
822 //\r
823 // Only the most significant bit can be used as divisor.\r
824 //\r
825 if (((Divisor - 1) & Divisor) != 0) {\r
826 Divisor = 1 << (HighBitSet32 (Divisor) + 1);\r
827 }\r
828 ASSERT (Divisor <= 0x80);\r
829 ClockCtrl = (Divisor & 0xFF) << 8;\r
830 } else {\r
e27ccaba 831 DEBUG ((DEBUG_ERROR, "Unknown SD Host Controller Spec version [0x%x]!!!\n", ControllerVer));\r
48555339
FT
832 return EFI_UNSUPPORTED;\r
833 }\r
834\r
835 //\r
836 // Stop bus clock at first\r
837 //\r
838 Status = SdMmcHcStopClock (PciIo, Slot);\r
839 if (EFI_ERROR (Status)) {\r
840 return Status;\r
841 }\r
842\r
843 //\r
844 // Supply clock frequency with specified divisor\r
845 //\r
846 ClockCtrl |= BIT0;\r
847 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, FALSE, sizeof (ClockCtrl), &ClockCtrl);\r
848 if (EFI_ERROR (Status)) {\r
e27ccaba 849 DEBUG ((DEBUG_ERROR, "Set SDCLK Frequency Select and Internal Clock Enable fields fails\n"));\r
48555339
FT
850 return Status;\r
851 }\r
852\r
853 //\r
854 // Wait Internal Clock Stable in the Clock Control register to be 1\r
855 //\r
856 Status = SdMmcHcWaitMmioSet (\r
857 PciIo,\r
858 Slot,\r
859 SD_MMC_HC_CLOCK_CTRL,\r
860 sizeof (ClockCtrl),\r
861 BIT1,\r
862 BIT1,\r
863 SD_MMC_HC_GENERIC_TIMEOUT\r
864 );\r
865 if (EFI_ERROR (Status)) {\r
866 return Status;\r
867 }\r
868\r
869 //\r
870 // Set SD Clock Enable in the Clock Control register to 1\r
871 //\r
872 ClockCtrl = BIT2;\r
873 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_CLOCK_CTRL, sizeof (ClockCtrl), &ClockCtrl);\r
874\r
875 return Status;\r
876}\r
877\r
878/**\r
879 SD/MMC bus power control.\r
880\r
881 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.\r
882\r
883 @param[in] PciIo The PCI IO protocol instance.\r
884 @param[in] Slot The slot number of the SD card to send the command to.\r
885 @param[in] PowerCtrl The value setting to the power control register.\r
886\r
887 @retval TRUE There is a SD/MMC card attached.\r
888 @retval FALSE There is no a SD/MMC card attached.\r
889\r
890**/\r
891EFI_STATUS\r
892SdMmcHcPowerControl (\r
893 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
894 IN UINT8 Slot,\r
895 IN UINT8 PowerCtrl\r
896 )\r
897{\r
898 EFI_STATUS Status;\r
899\r
900 //\r
901 // Clr SD Bus Power\r
902 //\r
903 PowerCtrl &= (UINT8)~BIT0;\r
904 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl);\r
905 if (EFI_ERROR (Status)) {\r
906 return Status;\r
907 }\r
908\r
909 //\r
910 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register\r
911 //\r
912 PowerCtrl |= BIT0;\r
913 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_POWER_CTRL, FALSE, sizeof (PowerCtrl), &PowerCtrl);\r
914\r
915 return Status;\r
916}\r
917\r
918/**\r
919 Set the SD/MMC bus width.\r
920\r
921 Refer to SD Host Controller Simplified spec 3.0 Section 3.4 for details.\r
922\r
923 @param[in] PciIo The PCI IO protocol instance.\r
924 @param[in] Slot The slot number of the SD card to send the command to.\r
925 @param[in] BusWidth The bus width used by the SD/MMC device, it must be 1, 4 or 8.\r
926\r
927 @retval EFI_SUCCESS The bus width is set successfully.\r
928 @retval Others The bus width isn't set successfully.\r
929\r
930**/\r
931EFI_STATUS\r
932SdMmcHcSetBusWidth (\r
933 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
934 IN UINT8 Slot,\r
935 IN UINT16 BusWidth\r
936 )\r
937{\r
938 EFI_STATUS Status;\r
939 UINT8 HostCtrl1;\r
940\r
941 if (BusWidth == 1) {\r
942 HostCtrl1 = (UINT8)~(BIT5 | BIT1);\r
943 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
944 } else if (BusWidth == 4) {\r
945 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1);\r
946 if (EFI_ERROR (Status)) {\r
947 return Status;\r
948 }\r
949 HostCtrl1 |= BIT1;\r
950 HostCtrl1 &= (UINT8)~BIT5;\r
951 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1);\r
952 } else if (BusWidth == 8) {\r
953 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, TRUE, sizeof (HostCtrl1), &HostCtrl1);\r
954 if (EFI_ERROR (Status)) {\r
955 return Status;\r
956 }\r
957 HostCtrl1 &= (UINT8)~BIT1;\r
958 HostCtrl1 |= BIT5;\r
959 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, FALSE, sizeof (HostCtrl1), &HostCtrl1);\r
960 } else {\r
961 ASSERT (FALSE);\r
962 return EFI_INVALID_PARAMETER;\r
963 }\r
964\r
965 return Status;\r
966}\r
967\r
b5547b9c
AS
968/**\r
969 Configure V4 controller enhancements at initialization.\r
970\r
971 @param[in] PciIo The PCI IO protocol instance.\r
972 @param[in] Slot The slot number of the SD card to send the command to.\r
973 @param[in] Capability The capability of the slot.\r
974 @param[in] ControllerVer The version of host controller.\r
975\r
976 @retval EFI_SUCCESS The clock is supplied successfully.\r
977\r
978**/\r
979EFI_STATUS\r
980SdMmcHcInitV4Enhancements (\r
981 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
982 IN UINT8 Slot,\r
983 IN SD_MMC_HC_SLOT_CAP Capability,\r
984 IN UINT16 ControllerVer\r
985 )\r
986{\r
987 EFI_STATUS Status;\r
988 UINT16 HostCtrl2;\r
989\r
990 //\r
991 // Check if controller version V4 or higher\r
992 //\r
993 if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) {\r
994 HostCtrl2 = SD_MMC_HC_V4_EN;\r
995 //\r
996 // Check if V4 64bit support is available\r
997 //\r
998 if (Capability.SysBus64V4 != 0) {\r
999 HostCtrl2 |= SD_MMC_HC_64_ADDR_EN;\r
1000 DEBUG ((DEBUG_INFO, "Enabled V4 64 bit system bus support\n"));\r
1001 }\r
1002 //\r
1003 // Check if controller version V4.10 or higher\r
1004 //\r
1005 if (ControllerVer >= SD_MMC_HC_CTRL_VER_410) {\r
1006 HostCtrl2 |= SD_MMC_HC_26_DATA_LEN_ADMA_EN;\r
1007 DEBUG ((DEBUG_INFO, "Enabled V4 26 bit data length ADMA support\n"));\r
1008 }\r
1009 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
1010 if (EFI_ERROR (Status)) {\r
1011 return Status;\r
1012 }\r
1013 }\r
1014\r
1015 return EFI_SUCCESS;\r
1016}\r
1017\r
48555339
FT
1018/**\r
1019 Supply SD/MMC card with lowest clock frequency at initialization.\r
1020\r
1021 @param[in] PciIo The PCI IO protocol instance.\r
1022 @param[in] Slot The slot number of the SD card to send the command to.\r
7f3b0bad 1023 @param[in] BaseClkFreq The base clock frequency of host controller in MHz.\r
b5547b9c 1024 @param[in] ControllerVer The version of host controller.\r
48555339
FT
1025\r
1026 @retval EFI_SUCCESS The clock is supplied successfully.\r
1027 @retval Others The clock isn't supplied successfully.\r
1028\r
1029**/\r
1030EFI_STATUS\r
1031SdMmcHcInitClockFreq (\r
1032 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
1033 IN UINT8 Slot,\r
b5547b9c
AS
1034 IN UINT32 BaseClkFreq,\r
1035 IN UINT16 ControllerVer\r
48555339
FT
1036 )\r
1037{\r
1038 EFI_STATUS Status;\r
1039 UINT32 InitFreq;\r
1040\r
1041 //\r
7f3b0bad
MW
1042 // According to SDHCI specification ver. 4.2, BaseClkFreq field value of\r
1043 // the Capability Register 1 can be zero, which means a need for obtaining\r
1044 // the clock frequency via another method. Fail in case it is not updated\r
1045 // by SW at this point.\r
48555339 1046 //\r
7f3b0bad 1047 if (BaseClkFreq == 0) {\r
48555339
FT
1048 //\r
1049 // Don't support get Base Clock Frequency information via another method\r
1050 //\r
1051 return EFI_UNSUPPORTED;\r
1052 }\r
1053 //\r
1054 // Supply 400KHz clock frequency at initialization phase.\r
1055 //\r
1056 InitFreq = 400;\r
b5547b9c 1057 Status = SdMmcHcClockSupply (PciIo, Slot, InitFreq, BaseClkFreq, ControllerVer);\r
48555339
FT
1058 return Status;\r
1059}\r
1060\r
1061/**\r
1062 Supply SD/MMC card with maximum voltage at initialization.\r
1063\r
1064 Refer to SD Host Controller Simplified spec 3.0 Section 3.3 for details.\r
1065\r
1066 @param[in] PciIo The PCI IO protocol instance.\r
1067 @param[in] Slot The slot number of the SD card to send the command to.\r
1068 @param[in] Capability The capability of the slot.\r
1069\r
1070 @retval EFI_SUCCESS The voltage is supplied successfully.\r
1071 @retval Others The voltage isn't supplied successfully.\r
1072\r
1073**/\r
1074EFI_STATUS\r
1075SdMmcHcInitPowerVoltage (\r
1076 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
1077 IN UINT8 Slot,\r
1078 IN SD_MMC_HC_SLOT_CAP Capability\r
1079 )\r
1080{\r
1081 EFI_STATUS Status;\r
1082 UINT8 MaxVoltage;\r
1083 UINT8 HostCtrl2;\r
1084\r
1085 //\r
1086 // Calculate supported maximum voltage according to SD Bus Voltage Select\r
1087 //\r
1088 if (Capability.Voltage33 != 0) {\r
1089 //\r
1090 // Support 3.3V\r
1091 //\r
1092 MaxVoltage = 0x0E;\r
1093 } else if (Capability.Voltage30 != 0) {\r
1094 //\r
1095 // Support 3.0V\r
1096 //\r
1097 MaxVoltage = 0x0C;\r
1098 } else if (Capability.Voltage18 != 0) {\r
1099 //\r
1100 // Support 1.8V\r
1101 //\r
1102 MaxVoltage = 0x0A;\r
1103 HostCtrl2 = BIT3;\r
1104 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
1105 gBS->Stall (5000);\r
1106 if (EFI_ERROR (Status)) {\r
1107 return Status;\r
1108 }\r
1109 } else {\r
1110 ASSERT (FALSE);\r
1111 return EFI_DEVICE_ERROR;\r
1112 }\r
1113\r
1114 //\r
1115 // Set SD Bus Voltage Select and SD Bus Power fields in Power Control Register\r
1116 //\r
1117 Status = SdMmcHcPowerControl (PciIo, Slot, MaxVoltage);\r
1118\r
1119 return Status;\r
1120}\r
1121\r
1122/**\r
1123 Initialize the Timeout Control register with most conservative value at initialization.\r
1124\r
1125 Refer to SD Host Controller Simplified spec 3.0 Section 2.2.15 for details.\r
1126\r
1127 @param[in] PciIo The PCI IO protocol instance.\r
1128 @param[in] Slot The slot number of the SD card to send the command to.\r
1129\r
1130 @retval EFI_SUCCESS The timeout control register is configured successfully.\r
1131 @retval Others The timeout control register isn't configured successfully.\r
1132\r
1133**/\r
1134EFI_STATUS\r
1135SdMmcHcInitTimeoutCtrl (\r
1136 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
1137 IN UINT8 Slot\r
1138 )\r
1139{\r
1140 EFI_STATUS Status;\r
1141 UINT8 Timeout;\r
1142\r
1143 Timeout = 0x0E;\r
1144 Status = SdMmcHcRwMmio (PciIo, Slot, SD_MMC_HC_TIMEOUT_CTRL, FALSE, sizeof (Timeout), &Timeout);\r
1145\r
1146 return Status;\r
1147}\r
1148\r
1149/**\r
1150 Initial SD/MMC host controller with lowest clock frequency, max power and max timeout value\r
1151 at initialization.\r
1152\r
b23fc39c 1153 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
48555339 1154 @param[in] Slot The slot number of the SD card to send the command to.\r
48555339
FT
1155\r
1156 @retval EFI_SUCCESS The host controller is initialized successfully.\r
1157 @retval Others The host controller isn't initialized successfully.\r
1158\r
1159**/\r
1160EFI_STATUS\r
1161SdMmcHcInitHost (\r
b23fc39c
AB
1162 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
1163 IN UINT8 Slot\r
48555339
FT
1164 )\r
1165{\r
b23fc39c
AB
1166 EFI_STATUS Status;\r
1167 EFI_PCI_IO_PROTOCOL *PciIo;\r
1168 SD_MMC_HC_SLOT_CAP Capability;\r
1169\r
1170 //\r
1171 // Notify the SD/MMC override protocol that we are about to initialize\r
1172 // the SD/MMC host controller.\r
1173 //\r
1174 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
1175 Status = mOverride->NotifyPhase (\r
1176 Private->ControllerHandle,\r
1177 Slot,\r
49c99534
MW
1178 EdkiiSdMmcInitHostPre,\r
1179 NULL);\r
b23fc39c
AB
1180 if (EFI_ERROR (Status)) {\r
1181 DEBUG ((DEBUG_WARN,\r
1182 "%a: SD/MMC pre init notifier callback failed - %r\n",\r
1183 __FUNCTION__, Status));\r
1184 return Status;\r
1185 }\r
1186 }\r
1187\r
1188 PciIo = Private->PciIo;\r
1189 Capability = Private->Capability[Slot];\r
48555339 1190\r
b5547b9c
AS
1191 Status = SdMmcHcInitV4Enhancements (PciIo, Slot, Capability, Private->ControllerVersion[Slot]);\r
1192 if (EFI_ERROR (Status)) {\r
1193 return Status;\r
1194 }\r
1195\r
1196 Status = SdMmcHcInitClockFreq (PciIo, Slot, Private->BaseClkFreq[Slot], Private->ControllerVersion[Slot]);\r
48555339
FT
1197 if (EFI_ERROR (Status)) {\r
1198 return Status;\r
1199 }\r
1200\r
1201 Status = SdMmcHcInitPowerVoltage (PciIo, Slot, Capability);\r
1202 if (EFI_ERROR (Status)) {\r
1203 return Status;\r
1204 }\r
1205\r
1206 Status = SdMmcHcInitTimeoutCtrl (PciIo, Slot);\r
b23fc39c
AB
1207 if (EFI_ERROR (Status)) {\r
1208 return Status;\r
1209 }\r
1210\r
1211 //\r
1212 // Notify the SD/MMC override protocol that we are have just initialized\r
1213 // the SD/MMC host controller.\r
1214 //\r
1215 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
1216 Status = mOverride->NotifyPhase (\r
1217 Private->ControllerHandle,\r
1218 Slot,\r
49c99534
MW
1219 EdkiiSdMmcInitHostPost,\r
1220 NULL);\r
b23fc39c
AB
1221 if (EFI_ERROR (Status)) {\r
1222 DEBUG ((DEBUG_WARN,\r
1223 "%a: SD/MMC post init notifier callback failed - %r\n",\r
1224 __FUNCTION__, Status));\r
1225 }\r
1226 }\r
48555339
FT
1227 return Status;\r
1228}\r
1229\r
a4708009
TM
1230/**\r
1231 Set SD Host Controler control 2 registry according to selected speed.\r
1232\r
1233 @param[in] ControllerHandle The handle of the controller.\r
1234 @param[in] PciIo The PCI IO protocol instance.\r
1235 @param[in] Slot The slot number of the SD card to send the command to.\r
1236 @param[in] Timing The timing to select.\r
1237\r
1238 @retval EFI_SUCCESS The timing is set successfully.\r
1239 @retval Others The timing isn't set successfully.\r
1240**/\r
1241EFI_STATUS\r
1242SdMmcHcUhsSignaling (\r
1243 IN EFI_HANDLE ControllerHandle,\r
1244 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
1245 IN UINT8 Slot,\r
1246 IN SD_MMC_BUS_MODE Timing\r
1247 )\r
1248{\r
1249 EFI_STATUS Status;\r
1250 UINT8 HostCtrl2;\r
1251\r
1252 HostCtrl2 = (UINT8)~SD_MMC_HC_CTRL_UHS_MASK;\r
1253 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
1254 if (EFI_ERROR (Status)) {\r
1255 return Status;\r
1256 }\r
1257\r
1258 switch (Timing) {\r
1259 case SdMmcUhsSdr12:\r
1260 HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR12;\r
1261 break;\r
1262 case SdMmcUhsSdr25:\r
1263 HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR25;\r
1264 break;\r
1265 case SdMmcUhsSdr50:\r
1266 HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR50;\r
1267 break;\r
1268 case SdMmcUhsSdr104:\r
1269 HostCtrl2 = SD_MMC_HC_CTRL_UHS_SDR104;\r
1270 break;\r
1271 case SdMmcUhsDdr50:\r
1272 HostCtrl2 = SD_MMC_HC_CTRL_UHS_DDR50;\r
1273 break;\r
1274 case SdMmcMmcLegacy:\r
1275 HostCtrl2 = SD_MMC_HC_CTRL_MMC_LEGACY;\r
1276 break;\r
1277 case SdMmcMmcHsSdr:\r
1278 HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_SDR;\r
1279 break;\r
1280 case SdMmcMmcHsDdr:\r
1281 HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS_DDR;\r
1282 break;\r
1283 case SdMmcMmcHs200:\r
1284 HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS200;\r
1285 break;\r
1286 case SdMmcMmcHs400:\r
1287 HostCtrl2 = SD_MMC_HC_CTRL_MMC_HS400;\r
1288 break;\r
1289 default:\r
1290 HostCtrl2 = 0;\r
1291 break;\r
1292 }\r
1293 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL2, sizeof (HostCtrl2), &HostCtrl2);\r
1294 if (EFI_ERROR (Status)) {\r
1295 return Status;\r
1296 }\r
1297\r
1298 if (mOverride != NULL && mOverride->NotifyPhase != NULL) {\r
1299 Status = mOverride->NotifyPhase (\r
1300 ControllerHandle,\r
1301 Slot,\r
1302 EdkiiSdMmcUhsSignaling,\r
1303 &Timing\r
1304 );\r
1305 if (EFI_ERROR (Status)) {\r
1306 DEBUG ((\r
1307 DEBUG_ERROR,\r
1308 "%a: SD/MMC uhs signaling notifier callback failed - %r\n",\r
1309 __FUNCTION__,\r
1310 Status\r
1311 ));\r
1312 return Status;\r
1313 }\r
1314 }\r
1315\r
1316 return EFI_SUCCESS;\r
1317}\r
1318\r
48555339
FT
1319/**\r
1320 Turn on/off LED.\r
1321\r
1322 @param[in] PciIo The PCI IO protocol instance.\r
1323 @param[in] Slot The slot number of the SD card to send the command to.\r
1324 @param[in] On The boolean to turn on/off LED.\r
1325\r
1326 @retval EFI_SUCCESS The LED is turned on/off successfully.\r
1327 @retval Others The LED isn't turned on/off successfully.\r
1328\r
1329**/\r
1330EFI_STATUS\r
1331SdMmcHcLedOnOff (\r
1332 IN EFI_PCI_IO_PROTOCOL *PciIo,\r
1333 IN UINT8 Slot,\r
1334 IN BOOLEAN On\r
1335 )\r
1336{\r
1337 EFI_STATUS Status;\r
1338 UINT8 HostCtrl1;\r
1339\r
1340 if (On) {\r
1341 HostCtrl1 = BIT0;\r
1342 Status = SdMmcHcOrMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
1343 } else {\r
1344 HostCtrl1 = (UINT8)~BIT0;\r
1345 Status = SdMmcHcAndMmio (PciIo, Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
1346 }\r
1347\r
1348 return Status;\r
1349}\r
1350\r
1351/**\r
1352 Build ADMA descriptor table for transfer.\r
1353\r
b5547b9c 1354 Refer to SD Host Controller Simplified spec 4.2 Section 1.13 for details.\r
48555339
FT
1355\r
1356 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
b5547b9c 1357 @param[in] ControllerVer The version of host controller.\r
48555339
FT
1358\r
1359 @retval EFI_SUCCESS The ADMA descriptor table is created successfully.\r
1360 @retval Others The ADMA descriptor table isn't created successfully.\r
1361\r
1362**/\r
1363EFI_STATUS\r
1364BuildAdmaDescTable (\r
b5547b9c
AS
1365 IN SD_MMC_HC_TRB *Trb,\r
1366 IN UINT16 ControllerVer\r
48555339
FT
1367 )\r
1368{\r
1369 EFI_PHYSICAL_ADDRESS Data;\r
1370 UINT64 DataLen;\r
1371 UINT64 Entries;\r
1372 UINT32 Index;\r
1373 UINT64 Remaining;\r
b5547b9c 1374 UINT64 Address;\r
48555339
FT
1375 UINTN TableSize;\r
1376 EFI_PCI_IO_PROTOCOL *PciIo;\r
1377 EFI_STATUS Status;\r
1378 UINTN Bytes;\r
b5547b9c
AS
1379 BOOLEAN AddressingMode64;\r
1380 BOOLEAN DataLength26;\r
1381 UINT32 AdmaMaxDataPerLine;\r
1382 UINT32 DescSize;\r
1383 VOID *AdmaDesc;\r
1384\r
1385 AddressingMode64 = FALSE;\r
1386 DataLength26 = FALSE;\r
1387 AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_16B;\r
1388 DescSize = sizeof (SD_MMC_HC_ADMA_32_DESC_LINE);\r
1389 AdmaDesc = NULL;\r
48555339
FT
1390\r
1391 Data = Trb->DataPhy;\r
1392 DataLen = Trb->DataLen;\r
1393 PciIo = Trb->Private->PciIo;\r
b5547b9c 1394\r
48555339 1395 //\r
b5547b9c 1396 // Detect whether 64bit addressing is supported.\r
48555339 1397 //\r
b5547b9c
AS
1398 if (ControllerVer >= SD_MMC_HC_CTRL_VER_400) {\r
1399 Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
1400 SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN);\r
1401 if (!EFI_ERROR (Status)) {\r
1402 AddressingMode64 = TRUE;\r
1403 DescSize = sizeof (SD_MMC_HC_ADMA_64_DESC_LINE);\r
1404 }\r
1405 }\r
1406 //\r
1407 // Check for valid ranges in 32bit ADMA Descriptor Table\r
1408 //\r
1409 if (!AddressingMode64 &&\r
1410 ((Data >= 0x100000000ul) || ((Data + DataLen) > 0x100000000ul))) {\r
48555339
FT
1411 return EFI_INVALID_PARAMETER;\r
1412 }\r
1413 //\r
b5547b9c 1414 // Check address field alignment\r
48555339 1415 //\r
b5547b9c
AS
1416 if (AddressingMode64) {\r
1417 //\r
1418 // Address field shall be set on 64-bit boundary (Lower 3-bit is always set to 0)\r
1419 //\r
1420 if ((Data & (BIT0 | BIT1 | BIT2)) != 0) {\r
1421 DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 8 bytes boundary!\n", Data));\r
1422 }\r
1423 } else {\r
1424 //\r
1425 // Address field shall be set on 32-bit boundary (Lower 2-bit is always set to 0)\r
1426 //\r
1427 if ((Data & (BIT0 | BIT1)) != 0) {\r
1428 DEBUG ((DEBUG_INFO, "The buffer [0x%x] to construct ADMA desc is not aligned to 4 bytes boundary!\n", Data));\r
1429 }\r
1430 }\r
1431 //\r
1432 // Detect whether 26bit data length is supported.\r
1433 //\r
1434 Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
1435 SD_MMC_HC_26_DATA_LEN_ADMA_EN, SD_MMC_HC_26_DATA_LEN_ADMA_EN);\r
1436 if (!EFI_ERROR (Status)) {\r
1437 DataLength26 = TRUE;\r
1438 AdmaMaxDataPerLine = ADMA_MAX_DATA_PER_LINE_26B;\r
48555339
FT
1439 }\r
1440\r
b5547b9c
AS
1441 Entries = DivU64x32 ((DataLen + AdmaMaxDataPerLine - 1), AdmaMaxDataPerLine);\r
1442 TableSize = (UINTN)MultU64x32 (Entries, DescSize);\r
48555339
FT
1443 Trb->AdmaPages = (UINT32)EFI_SIZE_TO_PAGES (TableSize);\r
1444 Status = PciIo->AllocateBuffer (\r
1445 PciIo,\r
1446 AllocateAnyPages,\r
1447 EfiBootServicesData,\r
1448 EFI_SIZE_TO_PAGES (TableSize),\r
b5547b9c 1449 (VOID **)&AdmaDesc,\r
48555339
FT
1450 0\r
1451 );\r
1452 if (EFI_ERROR (Status)) {\r
1453 return EFI_OUT_OF_RESOURCES;\r
1454 }\r
b5547b9c 1455 ZeroMem (AdmaDesc, TableSize);\r
48555339
FT
1456 Bytes = TableSize;\r
1457 Status = PciIo->Map (\r
1458 PciIo,\r
1459 EfiPciIoOperationBusMasterCommonBuffer,\r
b5547b9c 1460 AdmaDesc,\r
48555339
FT
1461 &Bytes,\r
1462 &Trb->AdmaDescPhy,\r
1463 &Trb->AdmaMap\r
1464 );\r
1465\r
1466 if (EFI_ERROR (Status) || (Bytes != TableSize)) {\r
1467 //\r
1468 // Map error or unable to map the whole RFis buffer into a contiguous region.\r
1469 //\r
1470 PciIo->FreeBuffer (\r
1471 PciIo,\r
1472 EFI_SIZE_TO_PAGES (TableSize),\r
b5547b9c 1473 AdmaDesc\r
48555339
FT
1474 );\r
1475 return EFI_OUT_OF_RESOURCES;\r
1476 }\r
1477\r
b5547b9c
AS
1478 if ((!AddressingMode64) &&\r
1479 (UINT64)(UINTN)Trb->AdmaDescPhy > 0x100000000ul) {\r
48555339
FT
1480 //\r
1481 // The ADMA doesn't support 64bit addressing.\r
1482 //\r
1483 PciIo->Unmap (\r
1484 PciIo,\r
1485 Trb->AdmaMap\r
1486 );\r
1487 PciIo->FreeBuffer (\r
1488 PciIo,\r
1489 EFI_SIZE_TO_PAGES (TableSize),\r
b5547b9c 1490 AdmaDesc\r
48555339
FT
1491 );\r
1492 return EFI_DEVICE_ERROR;\r
1493 }\r
1494\r
1495 Remaining = DataLen;\r
b5547b9c
AS
1496 Address = Data;\r
1497 if (!AddressingMode64) {\r
1498 Trb->Adma32Desc = AdmaDesc;\r
1499 Trb->Adma64Desc = NULL;\r
1500 } else {\r
1501 Trb->Adma64Desc = AdmaDesc;\r
1502 Trb->Adma32Desc = NULL;\r
1503 }\r
48555339 1504 for (Index = 0; Index < Entries; Index++) {\r
b5547b9c
AS
1505 if (!AddressingMode64) {\r
1506 if (Remaining <= AdmaMaxDataPerLine) {\r
1507 Trb->Adma32Desc[Index].Valid = 1;\r
1508 Trb->Adma32Desc[Index].Act = 2;\r
1509 if (DataLength26) {\r
46f4c967 1510 Trb->Adma32Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
b5547b9c
AS
1511 }\r
1512 Trb->Adma32Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
1513 Trb->Adma32Desc[Index].Address = (UINT32)Address;\r
1514 break;\r
1515 } else {\r
1516 Trb->Adma32Desc[Index].Valid = 1;\r
1517 Trb->Adma32Desc[Index].Act = 2;\r
1518 if (DataLength26) {\r
1519 Trb->Adma32Desc[Index].UpperLength = 0;\r
1520 }\r
1521 Trb->Adma32Desc[Index].LowerLength = 0;\r
1522 Trb->Adma32Desc[Index].Address = (UINT32)Address;\r
1523 }\r
48555339 1524 } else {\r
b5547b9c
AS
1525 if (Remaining <= AdmaMaxDataPerLine) {\r
1526 Trb->Adma64Desc[Index].Valid = 1;\r
1527 Trb->Adma64Desc[Index].Act = 2;\r
1528 if (DataLength26) {\r
46f4c967 1529 Trb->Adma64Desc[Index].UpperLength = (UINT16)RShiftU64 (Remaining, 16);\r
b5547b9c
AS
1530 }\r
1531 Trb->Adma64Desc[Index].LowerLength = (UINT16)(Remaining & MAX_UINT16);\r
1532 Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address;\r
46f4c967 1533 Trb->Adma64Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
b5547b9c
AS
1534 break;\r
1535 } else {\r
1536 Trb->Adma64Desc[Index].Valid = 1;\r
1537 Trb->Adma64Desc[Index].Act = 2;\r
1538 if (DataLength26) {\r
1539 Trb->Adma64Desc[Index].UpperLength = 0;\r
1540 }\r
1541 Trb->Adma64Desc[Index].LowerLength = 0;\r
1542 Trb->Adma64Desc[Index].LowerAddress = (UINT32)Address;\r
46f4c967 1543 Trb->Adma64Desc[Index].UpperAddress = (UINT32)RShiftU64 (Address, 32);\r
b5547b9c 1544 }\r
48555339
FT
1545 }\r
1546\r
b5547b9c
AS
1547 Remaining -= AdmaMaxDataPerLine;\r
1548 Address += AdmaMaxDataPerLine;\r
48555339
FT
1549 }\r
1550\r
1551 //\r
1552 // Set the last descriptor line as end of descriptor table\r
1553 //\r
b5547b9c 1554 AddressingMode64 ? (Trb->Adma64Desc[Index].End = 1) : (Trb->Adma32Desc[Index].End = 1);\r
48555339
FT
1555 return EFI_SUCCESS;\r
1556}\r
1557\r
1558/**\r
1559 Create a new TRB for the SD/MMC cmd request.\r
1560\r
1561 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
1562 @param[in] Slot The slot number of the SD card to send the command to.\r
1563 @param[in] Packet A pointer to the SD command data structure.\r
1564 @param[in] Event If Event is NULL, blocking I/O is performed. If Event is\r
1565 not NULL, then nonblocking I/O is performed, and Event\r
1566 will be signaled when the Packet completes.\r
1567\r
1568 @return Created Trb or NULL.\r
1569\r
1570**/\r
1571SD_MMC_HC_TRB *\r
1572SdMmcCreateTrb (\r
1573 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
1574 IN UINT8 Slot,\r
1575 IN EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet,\r
1576 IN EFI_EVENT Event\r
1577 )\r
1578{\r
1579 SD_MMC_HC_TRB *Trb;\r
1580 EFI_STATUS Status;\r
1581 EFI_TPL OldTpl;\r
1582 EFI_PCI_IO_PROTOCOL_OPERATION Flag;\r
1583 EFI_PCI_IO_PROTOCOL *PciIo;\r
1584 UINTN MapLength;\r
1585\r
1586 Trb = AllocateZeroPool (sizeof (SD_MMC_HC_TRB));\r
1587 if (Trb == NULL) {\r
1588 return NULL;\r
1589 }\r
1590\r
1591 Trb->Signature = SD_MMC_HC_TRB_SIG;\r
1592 Trb->Slot = Slot;\r
1593 Trb->BlockSize = 0x200;\r
1594 Trb->Packet = Packet;\r
1595 Trb->Event = Event;\r
1596 Trb->Started = FALSE;\r
1597 Trb->Timeout = Packet->Timeout;\r
1598 Trb->Private = Private;\r
1599\r
1600 if ((Packet->InTransferLength != 0) && (Packet->InDataBuffer != NULL)) {\r
1601 Trb->Data = Packet->InDataBuffer;\r
1602 Trb->DataLen = Packet->InTransferLength;\r
1603 Trb->Read = TRUE;\r
1604 } else if ((Packet->OutTransferLength != 0) && (Packet->OutDataBuffer != NULL)) {\r
1605 Trb->Data = Packet->OutDataBuffer;\r
1606 Trb->DataLen = Packet->OutTransferLength;\r
1607 Trb->Read = FALSE;\r
1608 } else if ((Packet->InTransferLength == 0) && (Packet->OutTransferLength == 0)) {\r
1609 Trb->Data = NULL;\r
1610 Trb->DataLen = 0;\r
1611 } else {\r
1612 goto Error;\r
1613 }\r
1614\r
54228046 1615 if ((Trb->DataLen != 0) && (Trb->DataLen < Trb->BlockSize)) {\r
e7e89b08
FT
1616 Trb->BlockSize = (UINT16)Trb->DataLen;\r
1617 }\r
1618\r
1619 if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
1620 (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
1621 ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
1622 (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
1623 Trb->Mode = SdMmcPioMode;\r
48555339 1624 } else {\r
e7e89b08
FT
1625 if (Trb->Read) {\r
1626 Flag = EfiPciIoOperationBusMasterWrite;\r
1627 } else {\r
1628 Flag = EfiPciIoOperationBusMasterRead;\r
48555339 1629 }\r
48555339 1630\r
e7e89b08
FT
1631 PciIo = Private->PciIo;\r
1632 if (Trb->DataLen != 0) {\r
1633 MapLength = Trb->DataLen;\r
1634 Status = PciIo->Map (\r
1635 PciIo,\r
1636 Flag,\r
1637 Trb->Data,\r
1638 &MapLength,\r
1639 &Trb->DataPhy,\r
1640 &Trb->DataMap\r
1641 );\r
1642 if (EFI_ERROR (Status) || (Trb->DataLen != MapLength)) {\r
1643 Status = EFI_BAD_BUFFER_SIZE;\r
1644 goto Error;\r
1645 }\r
48555339 1646 }\r
48555339 1647\r
e7e89b08
FT
1648 if (Trb->DataLen == 0) {\r
1649 Trb->Mode = SdMmcNoData;\r
1650 } else if (Private->Capability[Slot].Adma2 != 0) {\r
1651 Trb->Mode = SdMmcAdmaMode;\r
b5547b9c 1652 Status = BuildAdmaDescTable (Trb, Private->ControllerVersion[Slot]);\r
e7e89b08
FT
1653 if (EFI_ERROR (Status)) {\r
1654 PciIo->Unmap (PciIo, Trb->DataMap);\r
1655 goto Error;\r
1656 }\r
1657 } else if (Private->Capability[Slot].Sdma != 0) {\r
1658 Trb->Mode = SdMmcSdmaMode;\r
1659 } else {\r
1660 Trb->Mode = SdMmcPioMode;\r
48555339 1661 }\r
48555339
FT
1662 }\r
1663\r
1664 if (Event != NULL) {\r
3b1d8241 1665 OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
48555339
FT
1666 InsertTailList (&Private->Queue, &Trb->TrbList);\r
1667 gBS->RestoreTPL (OldTpl);\r
1668 }\r
1669\r
1670 return Trb;\r
1671\r
1672Error:\r
1673 SdMmcFreeTrb (Trb);\r
1674 return NULL;\r
1675}\r
1676\r
1677/**\r
1678 Free the resource used by the TRB.\r
1679\r
1680 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
1681\r
1682**/\r
1683VOID\r
1684SdMmcFreeTrb (\r
1685 IN SD_MMC_HC_TRB *Trb\r
1686 )\r
1687{\r
1688 EFI_PCI_IO_PROTOCOL *PciIo;\r
1689\r
1690 PciIo = Trb->Private->PciIo;\r
1691\r
1692 if (Trb->AdmaMap != NULL) {\r
1693 PciIo->Unmap (\r
1694 PciIo,\r
1695 Trb->AdmaMap\r
1696 );\r
1697 }\r
b5547b9c
AS
1698 if (Trb->Adma32Desc != NULL) {\r
1699 PciIo->FreeBuffer (\r
1700 PciIo,\r
1701 Trb->AdmaPages,\r
1702 Trb->Adma32Desc\r
1703 );\r
1704 }\r
1705 if (Trb->Adma64Desc != NULL) {\r
48555339
FT
1706 PciIo->FreeBuffer (\r
1707 PciIo,\r
1708 Trb->AdmaPages,\r
b5547b9c 1709 Trb->Adma64Desc\r
48555339
FT
1710 );\r
1711 }\r
1712 if (Trb->DataMap != NULL) {\r
1713 PciIo->Unmap (\r
1714 PciIo,\r
1715 Trb->DataMap\r
1716 );\r
1717 }\r
1718 FreePool (Trb);\r
1719 return;\r
1720}\r
1721\r
1722/**\r
1723 Check if the env is ready for execute specified TRB.\r
1724\r
1725 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
1726 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
1727\r
1728 @retval EFI_SUCCESS The env is ready for TRB execution.\r
1729 @retval EFI_NOT_READY The env is not ready for TRB execution.\r
1730 @retval Others Some erros happen.\r
1731\r
1732**/\r
1733EFI_STATUS\r
1734SdMmcCheckTrbEnv (\r
1735 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
1736 IN SD_MMC_HC_TRB *Trb\r
1737 )\r
1738{\r
1739 EFI_STATUS Status;\r
1740 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
1741 EFI_PCI_IO_PROTOCOL *PciIo;\r
1742 UINT32 PresentState;\r
1743\r
1744 Packet = Trb->Packet;\r
1745\r
1746 if ((Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc) ||\r
1747 (Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR1b) ||\r
1748 (Packet->SdMmcCmdBlk->ResponseType == SdMmcResponseTypeR5b)) {\r
1749 //\r
1750 // Wait Command Inhibit (CMD) and Command Inhibit (DAT) in\r
1751 // the Present State register to be 0\r
1752 //\r
1753 PresentState = BIT0 | BIT1;\r
48555339
FT
1754 } else {\r
1755 //\r
1756 // Wait Command Inhibit (CMD) in the Present State register\r
1757 // to be 0\r
1758 //\r
1759 PresentState = BIT0;\r
1760 }\r
1761\r
1762 PciIo = Private->PciIo;\r
1763 Status = SdMmcHcCheckMmioSet (\r
1764 PciIo,\r
1765 Trb->Slot,\r
1766 SD_MMC_HC_PRESENT_STATE,\r
1767 sizeof (PresentState),\r
1768 PresentState,\r
1769 0\r
1770 );\r
1771\r
1772 return Status;\r
1773}\r
1774\r
1775/**\r
1776 Wait for the env to be ready for execute specified TRB.\r
1777\r
1778 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
1779 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
1780\r
1781 @retval EFI_SUCCESS The env is ready for TRB execution.\r
1782 @retval EFI_TIMEOUT The env is not ready for TRB execution in time.\r
1783 @retval Others Some erros happen.\r
1784\r
1785**/\r
1786EFI_STATUS\r
1787SdMmcWaitTrbEnv (\r
1788 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
1789 IN SD_MMC_HC_TRB *Trb\r
1790 )\r
1791{\r
1792 EFI_STATUS Status;\r
1793 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
1794 UINT64 Timeout;\r
1795 BOOLEAN InfiniteWait;\r
1796\r
1797 //\r
1798 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register\r
1799 //\r
1800 Packet = Trb->Packet;\r
1801 Timeout = Packet->Timeout;\r
1802 if (Timeout == 0) {\r
1803 InfiniteWait = TRUE;\r
1804 } else {\r
1805 InfiniteWait = FALSE;\r
1806 }\r
1807\r
1808 while (InfiniteWait || (Timeout > 0)) {\r
1809 //\r
1810 // Check Trb execution result by reading Normal Interrupt Status register.\r
1811 //\r
1812 Status = SdMmcCheckTrbEnv (Private, Trb);\r
1813 if (Status != EFI_NOT_READY) {\r
1814 return Status;\r
1815 }\r
1816 //\r
1817 // Stall for 1 microsecond.\r
1818 //\r
1819 gBS->Stall (1);\r
1820\r
1821 Timeout--;\r
1822 }\r
1823\r
1824 return EFI_TIMEOUT;\r
1825}\r
1826\r
1827/**\r
1828 Execute the specified TRB.\r
1829\r
1830 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
1831 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
1832\r
1833 @retval EFI_SUCCESS The TRB is sent to host controller successfully.\r
1834 @retval Others Some erros happen when sending this request to the host controller.\r
1835\r
1836**/\r
1837EFI_STATUS\r
1838SdMmcExecTrb (\r
1839 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
1840 IN SD_MMC_HC_TRB *Trb\r
1841 )\r
1842{\r
1843 EFI_STATUS Status;\r
1844 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
1845 EFI_PCI_IO_PROTOCOL *PciIo;\r
1846 UINT16 Cmd;\r
1847 UINT16 IntStatus;\r
1848 UINT32 Argument;\r
b5547b9c 1849 UINT32 BlkCount;\r
48555339
FT
1850 UINT16 BlkSize;\r
1851 UINT16 TransMode;\r
1852 UINT8 HostCtrl1;\r
b5547b9c 1853 UINT64 SdmaAddr;\r
48555339 1854 UINT64 AdmaAddr;\r
b5547b9c
AS
1855 BOOLEAN AddressingMode64;\r
1856\r
1857 AddressingMode64 = FALSE;\r
48555339
FT
1858\r
1859 Packet = Trb->Packet;\r
1860 PciIo = Trb->Private->PciIo;\r
1861 //\r
1862 // Clear all bits in Error Interrupt Status Register\r
1863 //\r
1864 IntStatus = 0xFFFF;\r
1865 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ERR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
1866 if (EFI_ERROR (Status)) {\r
1867 return Status;\r
1868 }\r
1869 //\r
1870 // Clear all bits in Normal Interrupt Status Register excepts for Card Removal & Card Insertion bits.\r
1871 //\r
1872 IntStatus = 0xFF3F;\r
1873 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
1874 if (EFI_ERROR (Status)) {\r
1875 return Status;\r
1876 }\r
1877 //\r
1878 // Set Host Control 1 register DMA Select field\r
1879 //\r
1880 if (Trb->Mode == SdMmcAdmaMode) {\r
1881 HostCtrl1 = BIT4;\r
1882 Status = SdMmcHcOrMmio (PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL1, sizeof (HostCtrl1), &HostCtrl1);\r
1883 if (EFI_ERROR (Status)) {\r
1884 return Status;\r
1885 }\r
1886 }\r
1887\r
1888 SdMmcHcLedOnOff (PciIo, Trb->Slot, TRUE);\r
1889\r
b5547b9c
AS
1890 if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
1891 Status = SdMmcHcCheckMmioSet(PciIo, Trb->Slot, SD_MMC_HC_HOST_CTRL2, sizeof(UINT16),\r
1892 SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN, SD_MMC_HC_V4_EN|SD_MMC_HC_64_ADDR_EN);\r
1893 if (!EFI_ERROR (Status)) {\r
1894 AddressingMode64 = TRUE;\r
1895 }\r
1896 }\r
1897\r
48555339 1898 if (Trb->Mode == SdMmcSdmaMode) {\r
b5547b9c
AS
1899 if ((!AddressingMode64) &&\r
1900 ((UINT64)(UINTN)Trb->DataPhy >= 0x100000000ul)) {\r
48555339
FT
1901 return EFI_INVALID_PARAMETER;\r
1902 }\r
1903\r
b5547b9c
AS
1904 SdmaAddr = (UINT64)(UINTN)Trb->DataPhy;\r
1905\r
1906 if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
1907 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (UINT64), &SdmaAddr);\r
1908 } else {\r
1909 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, FALSE, sizeof (UINT32), &SdmaAddr);\r
1910 }\r
1911\r
48555339
FT
1912 if (EFI_ERROR (Status)) {\r
1913 return Status;\r
1914 }\r
1915 } else if (Trb->Mode == SdMmcAdmaMode) {\r
1916 AdmaAddr = (UINT64)(UINTN)Trb->AdmaDescPhy;\r
1917 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ADMA_SYS_ADDR, FALSE, sizeof (AdmaAddr), &AdmaAddr);\r
1918 if (EFI_ERROR (Status)) {\r
1919 return Status;\r
1920 }\r
1921 }\r
1922\r
1923 BlkSize = Trb->BlockSize;\r
1924 if (Trb->Mode == SdMmcSdmaMode) {\r
1925 //\r
1926 // Set SDMA boundary to be 512K bytes.\r
1927 //\r
1928 BlkSize |= 0x7000;\r
1929 }\r
1930\r
1931 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_SIZE, FALSE, sizeof (BlkSize), &BlkSize);\r
1932 if (EFI_ERROR (Status)) {\r
1933 return Status;\r
1934 }\r
1935\r
e7e89b08
FT
1936 BlkCount = 0;\r
1937 if (Trb->Mode != SdMmcNoData) {\r
1938 //\r
1939 // Calcuate Block Count.\r
1940 //\r
b5547b9c
AS
1941 BlkCount = (Trb->DataLen / Trb->BlockSize);\r
1942 }\r
1943 if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_410) {\r
1944 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_SDMA_ADDR, FALSE, sizeof (UINT32), &BlkCount);\r
1945 } else {\r
1946 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_BLK_COUNT, FALSE, sizeof (UINT16), &BlkCount);\r
e7e89b08 1947 }\r
48555339
FT
1948 if (EFI_ERROR (Status)) {\r
1949 return Status;\r
1950 }\r
1951\r
1952 Argument = Packet->SdMmcCmdBlk->CommandArgument;\r
1953 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_ARG1, FALSE, sizeof (Argument), &Argument);\r
1954 if (EFI_ERROR (Status)) {\r
1955 return Status;\r
1956 }\r
1957\r
1958 TransMode = 0;\r
1959 if (Trb->Mode != SdMmcNoData) {\r
1960 if (Trb->Mode != SdMmcPioMode) {\r
1961 TransMode |= BIT0;\r
1962 }\r
1963 if (Trb->Read) {\r
1964 TransMode |= BIT4;\r
1965 }\r
e7e89b08 1966 if (BlkCount > 1) {\r
48555339
FT
1967 TransMode |= BIT5 | BIT1;\r
1968 }\r
1969 //\r
1970 // Only SD memory card needs to use AUTO CMD12 feature.\r
1971 //\r
1972 if (Private->Slot[Trb->Slot].CardType == SdCardType) {\r
1973 if (BlkCount > 1) {\r
1974 TransMode |= BIT2;\r
1975 }\r
1976 }\r
1977 }\r
1978\r
1979 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_TRANS_MOD, FALSE, sizeof (TransMode), &TransMode);\r
1980 if (EFI_ERROR (Status)) {\r
1981 return Status;\r
1982 }\r
1983\r
1984 Cmd = (UINT16)LShiftU64(Packet->SdMmcCmdBlk->CommandIndex, 8);\r
1985 if (Packet->SdMmcCmdBlk->CommandType == SdMmcCommandTypeAdtc) {\r
1986 Cmd |= BIT5;\r
1987 }\r
1988 //\r
1989 // Convert ResponseType to value\r
1990 //\r
1991 if (Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeBc) {\r
1992 switch (Packet->SdMmcCmdBlk->ResponseType) {\r
1993 case SdMmcResponseTypeR1:\r
1994 case SdMmcResponseTypeR5:\r
1995 case SdMmcResponseTypeR6:\r
1996 case SdMmcResponseTypeR7:\r
1997 Cmd |= (BIT1 | BIT3 | BIT4);\r
1998 break;\r
1999 case SdMmcResponseTypeR2:\r
2000 Cmd |= (BIT0 | BIT3);\r
2001 break;\r
2002 case SdMmcResponseTypeR3:\r
2003 case SdMmcResponseTypeR4:\r
2004 Cmd |= BIT1;\r
2005 break;\r
2006 case SdMmcResponseTypeR1b:\r
2007 case SdMmcResponseTypeR5b:\r
2008 Cmd |= (BIT0 | BIT1 | BIT3 | BIT4);\r
2009 break;\r
2010 default:\r
2011 ASSERT (FALSE);\r
2012 break;\r
2013 }\r
2014 }\r
2015 //\r
2016 // Execute cmd\r
2017 //\r
2018 Status = SdMmcHcRwMmio (PciIo, Trb->Slot, SD_MMC_HC_COMMAND, FALSE, sizeof (Cmd), &Cmd);\r
2019 return Status;\r
2020}\r
2021\r
2022/**\r
2023 Check the TRB execution result.\r
2024\r
2025 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
2026 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
2027\r
2028 @retval EFI_SUCCESS The TRB is executed successfully.\r
2029 @retval EFI_NOT_READY The TRB is not completed for execution.\r
2030 @retval Others Some erros happen when executing this request.\r
2031\r
2032**/\r
2033EFI_STATUS\r
2034SdMmcCheckTrbResult (\r
2035 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
2036 IN SD_MMC_HC_TRB *Trb\r
2037 )\r
2038{\r
2039 EFI_STATUS Status;\r
2040 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
2041 UINT16 IntStatus;\r
2042 UINT32 Response[4];\r
b5547b9c 2043 UINT64 SdmaAddr;\r
48555339
FT
2044 UINT8 Index;\r
2045 UINT8 SwReset;\r
e7e89b08 2046 UINT32 PioLength;\r
48555339
FT
2047\r
2048 SwReset = 0;\r
2049 Packet = Trb->Packet;\r
2050 //\r
2051 // Check Trb execution result by reading Normal Interrupt Status register.\r
2052 //\r
2053 Status = SdMmcHcRwMmio (\r
2054 Private->PciIo,\r
2055 Trb->Slot,\r
2056 SD_MMC_HC_NOR_INT_STS,\r
2057 TRUE,\r
2058 sizeof (IntStatus),\r
2059 &IntStatus\r
2060 );\r
2061 if (EFI_ERROR (Status)) {\r
2062 goto Done;\r
2063 }\r
2064 //\r
2065 // Check Transfer Complete bit is set or not.\r
2066 //\r
2067 if ((IntStatus & BIT1) == BIT1) {\r
2068 if ((IntStatus & BIT15) == BIT15) {\r
2069 //\r
2070 // Read Error Interrupt Status register to check if the error is\r
2071 // Data Timeout Error.\r
2072 // If yes, treat it as success as Transfer Complete has higher\r
2073 // priority than Data Timeout Error.\r
2074 //\r
2075 Status = SdMmcHcRwMmio (\r
2076 Private->PciIo,\r
2077 Trb->Slot,\r
2078 SD_MMC_HC_ERR_INT_STS,\r
2079 TRUE,\r
2080 sizeof (IntStatus),\r
2081 &IntStatus\r
2082 );\r
2083 if (!EFI_ERROR (Status)) {\r
2084 if ((IntStatus & BIT4) == BIT4) {\r
2085 Status = EFI_SUCCESS;\r
2086 } else {\r
2087 Status = EFI_DEVICE_ERROR;\r
2088 }\r
2089 }\r
2090 }\r
2091\r
2092 goto Done;\r
2093 }\r
2094 //\r
2095 // Check if there is a error happened during cmd execution.\r
2096 // If yes, then do error recovery procedure to follow SD Host Controller\r
2097 // Simplified Spec 3.0 section 3.10.1.\r
2098 //\r
2099 if ((IntStatus & BIT15) == BIT15) {\r
2100 Status = SdMmcHcRwMmio (\r
2101 Private->PciIo,\r
2102 Trb->Slot,\r
2103 SD_MMC_HC_ERR_INT_STS,\r
2104 TRUE,\r
2105 sizeof (IntStatus),\r
2106 &IntStatus\r
2107 );\r
2108 if (EFI_ERROR (Status)) {\r
2109 goto Done;\r
2110 }\r
2111 if ((IntStatus & 0x0F) != 0) {\r
2112 SwReset |= BIT1;\r
2113 }\r
2114 if ((IntStatus & 0xF0) != 0) {\r
2115 SwReset |= BIT2;\r
2116 }\r
2117\r
2118 Status = SdMmcHcRwMmio (\r
2119 Private->PciIo,\r
2120 Trb->Slot,\r
2121 SD_MMC_HC_SW_RST,\r
2122 FALSE,\r
2123 sizeof (SwReset),\r
2124 &SwReset\r
2125 );\r
2126 if (EFI_ERROR (Status)) {\r
2127 goto Done;\r
2128 }\r
2129 Status = SdMmcHcWaitMmioSet (\r
2130 Private->PciIo,\r
2131 Trb->Slot,\r
2132 SD_MMC_HC_SW_RST,\r
2133 sizeof (SwReset),\r
2134 0xFF,\r
2135 0,\r
2136 SD_MMC_HC_GENERIC_TIMEOUT\r
2137 );\r
2138 if (EFI_ERROR (Status)) {\r
2139 goto Done;\r
2140 }\r
2141\r
2142 Status = EFI_DEVICE_ERROR;\r
2143 goto Done;\r
2144 }\r
2145 //\r
2146 // Check if DMA interrupt is signalled for the SDMA transfer.\r
2147 //\r
2148 if ((Trb->Mode == SdMmcSdmaMode) && ((IntStatus & BIT3) == BIT3)) {\r
2149 //\r
2150 // Clear DMA interrupt bit.\r
2151 //\r
2152 IntStatus = BIT3;\r
2153 Status = SdMmcHcRwMmio (\r
2154 Private->PciIo,\r
2155 Trb->Slot,\r
2156 SD_MMC_HC_NOR_INT_STS,\r
2157 FALSE,\r
2158 sizeof (IntStatus),\r
2159 &IntStatus\r
2160 );\r
2161 if (EFI_ERROR (Status)) {\r
2162 goto Done;\r
2163 }\r
2164 //\r
2165 // Update SDMA Address register.\r
2166 //\r
b5547b9c
AS
2167 SdmaAddr = SD_MMC_SDMA_ROUND_UP ((UINTN)Trb->DataPhy, SD_MMC_SDMA_BOUNDARY);\r
2168\r
2169 if (Private->ControllerVersion[Trb->Slot] >= SD_MMC_HC_CTRL_VER_400) {\r
2170 Status = SdMmcHcRwMmio (\r
2171 Private->PciIo,\r
2172 Trb->Slot,\r
2173 SD_MMC_HC_ADMA_SYS_ADDR,\r
2174 FALSE,\r
2175 sizeof (UINT64),\r
2176 &SdmaAddr\r
2177 );\r
2178 } else {\r
2179 Status = SdMmcHcRwMmio (\r
48555339
FT
2180 Private->PciIo,\r
2181 Trb->Slot,\r
2182 SD_MMC_HC_SDMA_ADDR,\r
2183 FALSE,\r
2184 sizeof (UINT32),\r
2185 &SdmaAddr\r
2186 );\r
b5547b9c
AS
2187 }\r
2188\r
48555339
FT
2189 if (EFI_ERROR (Status)) {\r
2190 goto Done;\r
2191 }\r
b5547b9c 2192 Trb->DataPhy = (UINT64)(UINTN)SdmaAddr;\r
48555339
FT
2193 }\r
2194\r
2195 if ((Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeAdtc) &&\r
2196 (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR1b) &&\r
2197 (Packet->SdMmcCmdBlk->ResponseType != SdMmcResponseTypeR5b)) {\r
2198 if ((IntStatus & BIT0) == BIT0) {\r
2199 Status = EFI_SUCCESS;\r
2200 goto Done;\r
2201 }\r
2202 }\r
2203\r
2204 if (((Private->Slot[Trb->Slot].CardType == EmmcCardType) &&\r
2205 (Packet->SdMmcCmdBlk->CommandIndex == EMMC_SEND_TUNING_BLOCK)) ||\r
2206 ((Private->Slot[Trb->Slot].CardType == SdCardType) &&\r
2207 (Packet->SdMmcCmdBlk->CommandIndex == SD_SEND_TUNING_BLOCK))) {\r
2208 //\r
e7e89b08
FT
2209 // When performing tuning procedure (Execute Tuning is set to 1) through PIO mode,\r
2210 // wait Buffer Read Ready bit of Normal Interrupt Status Register to be 1.\r
2211 // Refer to SD Host Controller Simplified Specification 3.0 figure 2-29 for details.\r
48555339 2212 //\r
e7e89b08
FT
2213 if ((IntStatus & BIT5) == BIT5) {\r
2214 //\r
2215 // Clear Buffer Read Ready interrupt at first.\r
2216 //\r
2217 IntStatus = BIT5;\r
2218 SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_NOR_INT_STS, FALSE, sizeof (IntStatus), &IntStatus);\r
2219 //\r
2220 // Read data out from Buffer Port register\r
2221 //\r
2222 for (PioLength = 0; PioLength < Trb->DataLen; PioLength += 4) {\r
2223 SdMmcHcRwMmio (Private->PciIo, Trb->Slot, SD_MMC_HC_BUF_DAT_PORT, TRUE, 4, (UINT8*)Trb->Data + PioLength);\r
2224 }\r
2225 Status = EFI_SUCCESS;\r
2226 goto Done;\r
2227 }\r
48555339
FT
2228 }\r
2229\r
2230 Status = EFI_NOT_READY;\r
2231Done:\r
2232 //\r
2233 // Get response data when the cmd is executed successfully.\r
2234 //\r
2235 if (!EFI_ERROR (Status)) {\r
2236 if (Packet->SdMmcCmdBlk->CommandType != SdMmcCommandTypeBc) {\r
2237 for (Index = 0; Index < 4; Index++) {\r
2238 Status = SdMmcHcRwMmio (\r
2239 Private->PciIo,\r
2240 Trb->Slot,\r
2241 SD_MMC_HC_RESPONSE + Index * 4,\r
2242 TRUE,\r
2243 sizeof (UINT32),\r
2244 &Response[Index]\r
2245 );\r
2246 if (EFI_ERROR (Status)) {\r
2247 SdMmcHcLedOnOff (Private->PciIo, Trb->Slot, FALSE);\r
2248 return Status;\r
2249 }\r
2250 }\r
2251 CopyMem (Packet->SdMmcStatusBlk, Response, sizeof (Response));\r
2252 }\r
2253 }\r
2254\r
2255 if (Status != EFI_NOT_READY) {\r
2256 SdMmcHcLedOnOff (Private->PciIo, Trb->Slot, FALSE);\r
2257 }\r
2258\r
2259 return Status;\r
2260}\r
2261\r
2262/**\r
2263 Wait for the TRB execution result.\r
2264\r
2265 @param[in] Private A pointer to the SD_MMC_HC_PRIVATE_DATA instance.\r
2266 @param[in] Trb The pointer to the SD_MMC_HC_TRB instance.\r
2267\r
2268 @retval EFI_SUCCESS The TRB is executed successfully.\r
2269 @retval Others Some erros happen when executing this request.\r
2270\r
2271**/\r
2272EFI_STATUS\r
2273SdMmcWaitTrbResult (\r
2274 IN SD_MMC_HC_PRIVATE_DATA *Private,\r
2275 IN SD_MMC_HC_TRB *Trb\r
2276 )\r
2277{\r
2278 EFI_STATUS Status;\r
2279 EFI_SD_MMC_PASS_THRU_COMMAND_PACKET *Packet;\r
2280 UINT64 Timeout;\r
2281 BOOLEAN InfiniteWait;\r
2282\r
2283 Packet = Trb->Packet;\r
2284 //\r
2285 // Wait Command Complete Interrupt Status bit in Normal Interrupt Status Register\r
2286 //\r
2287 Timeout = Packet->Timeout;\r
2288 if (Timeout == 0) {\r
2289 InfiniteWait = TRUE;\r
2290 } else {\r
2291 InfiniteWait = FALSE;\r
2292 }\r
2293\r
2294 while (InfiniteWait || (Timeout > 0)) {\r
2295 //\r
2296 // Check Trb execution result by reading Normal Interrupt Status register.\r
2297 //\r
2298 Status = SdMmcCheckTrbResult (Private, Trb);\r
2299 if (Status != EFI_NOT_READY) {\r
2300 return Status;\r
2301 }\r
2302 //\r
2303 // Stall for 1 microsecond.\r
2304 //\r
2305 gBS->Stall (1);\r
2306\r
2307 Timeout--;\r
2308 }\r
2309\r
2310 return EFI_TIMEOUT;\r
2311}\r
2312\r