Home | History | Annotate | Download | only in DwMmcHcDxe
      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
     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
     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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
    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
   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
   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
   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 *
   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