/** @file\r
This driver is used to manage SD/MMC PCI host controllers which are compliance\r
- with SD Host Controller Simplified Specification version 3.00.\r
+ with SD Host Controller Simplified Specification version 3.00 plus the 64-bit\r
+ System Addressing support in SD Host Controller Simplified Specification version\r
+ 4.20.\r
\r
It would expose EFI_SD_MMC_PASS_THRU_PROTOCOL for upper layer use.\r
\r
- Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.\r
- Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2018-2019, NVIDIA CORPORATION. All rights reserved.\r
+ Copyright (c) 2015 - 2020, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
NULL\r
};\r
\r
+#define SLOT_INIT_TEMPLATE {0, UnknownSlot, 0, 0, 0, 0, \\r
+ {EDKII_SD_MMC_BUS_WIDTH_IGNORE,\\r
+ EDKII_SD_MMC_CLOCK_FREQ_IGNORE,\\r
+ {EDKII_SD_MMC_DRIVER_STRENGTH_IGNORE}}}\r
+\r
//\r
// Template for SD/MMC host controller private data.\r
//\r
// Queue\r
INITIALIZE_LIST_HEAD_VARIABLE (gSdMmcPciHcTemplate.Queue),\r
{ // Slot\r
- {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0},\r
- {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}, {0, UnknownSlot, 0, 0, 0}\r
+ SLOT_INIT_TEMPLATE,\r
+ SLOT_INIT_TEMPLATE,\r
+ SLOT_INIT_TEMPLATE,\r
+ SLOT_INIT_TEMPLATE,\r
+ SLOT_INIT_TEMPLATE,\r
+ SLOT_INIT_TEMPLATE\r
},\r
{ // Capability\r
{0},\r
gBS->SignalEvent (TrbEvent);\r
return;\r
}\r
- }\r
- if ((Trb != NULL) && (Status != EFI_NOT_READY)) {\r
+ } else if ((Trb != NULL) && (Status == EFI_CRC_ERROR) && (Trb->Retries > 0)) {\r
+ Trb->Retries--;\r
+ Trb->Started = FALSE;\r
+ } else if ((Trb != NULL)) {\r
RemoveEntryList (Link);\r
Trb->Packet->TransactionStatus = Status;\r
TrbEvent = Trb->Event;\r
\r
return;\r
}\r
+\r
/**\r
Tests to see if this driver supports a given controller. If a child device is provided,\r
it further tests to see if this driver supports creating a handle for the specified child device.\r
Support64BitDma = TRUE;\r
for (Slot = FirstBar; Slot < (FirstBar + SlotNum); Slot++) {\r
Private->Slot[Slot].Enable = TRUE;\r
-\r
//\r
// Get SD/MMC Pci Host Controller Version\r
//\r
\r
Private->BaseClkFreq[Slot] = Private->Capability[Slot].BaseClkFreq;\r
\r
- if (mOverride != NULL && mOverride->Capability != NULL) {\r
- Status = mOverride->Capability (\r
- Controller,\r
- Slot,\r
- &Private->Capability[Slot],\r
- &Private->BaseClkFreq[Slot]\r
- );\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((DEBUG_WARN, "%a: Failed to override capability - %r\n",\r
- __FUNCTION__, Status));\r
- continue;\r
+ if (mOverride != NULL) {\r
+ if (mOverride->Capability != NULL) {\r
+ Status = mOverride->Capability (\r
+ Controller,\r
+ Slot,\r
+ &Private->Capability[Slot],\r
+ &Private->BaseClkFreq[Slot]\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_WARN, "%a: Failed to override capability - %r\n",\r
+ __FUNCTION__, Status));\r
+ continue;\r
+ }\r
+ }\r
+\r
+ if (mOverride->NotifyPhase != NULL) {\r
+ Status = mOverride->NotifyPhase (\r
+ Controller,\r
+ Slot,\r
+ EdkiiSdMmcGetOperatingParam,\r
+ (VOID*)&Private->Slot[Slot].OperatingParameters\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_WARN, "%a: Failed to get operating parameters, using defaults\n", __FUNCTION__));\r
+ }\r
}\r
}\r
+\r
DumpCapabilityReg (Slot, &Private->Capability[Slot]);\r
DEBUG ((\r
DEBUG_INFO,\r
// If any of the slots does not support 64b system bus\r
// do not enable 64b DMA in the PCI layer.\r
//\r
- if (Private->Capability[Slot].SysBus64V3 == 0 &&\r
- Private->Capability[Slot].SysBus64V4 == 0) {\r
+ if ((Private->ControllerVersion[Slot] == SD_MMC_HC_CTRL_VER_300 &&\r
+ Private->Capability[Slot].SysBus64V3 == 0) ||\r
+ (Private->ControllerVersion[Slot] == SD_MMC_HC_CTRL_VER_400 &&\r
+ Private->Capability[Slot].SysBus64V3 == 0) ||\r
+ (Private->ControllerVersion[Slot] >= SD_MMC_HC_CTRL_VER_410 &&\r
+ Private->Capability[Slot].SysBus64V4 == 0)) {\r
Support64BitDma = FALSE;\r
}\r
\r
return Status;\r
}\r
\r
+/**\r
+ Execute TRB synchronously.\r
+\r
+ @param[in] Private Pointer to driver private data.\r
+ @param[in] Trb Pointer to TRB to execute.\r
+\r
+ @retval EFI_SUCCESS TRB executed successfully.\r
+ @retval Other TRB failed.\r
+**/\r
+EFI_STATUS\r
+SdMmcPassThruExecSyncTrb (\r
+ IN SD_MMC_HC_PRIVATE_DATA *Private,\r
+ IN SD_MMC_HC_TRB *Trb\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_TPL OldTpl;\r
+\r
+ //\r
+ // Wait async I/O list is empty before execute sync I/O operation.\r
+ //\r
+ while (TRUE) {\r
+ OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
+ if (IsListEmpty (&Private->Queue)) {\r
+ gBS->RestoreTPL (OldTpl);\r
+ break;\r
+ }\r
+ gBS->RestoreTPL (OldTpl);\r
+ }\r
+\r
+ while (Trb->Retries) {\r
+ Status = SdMmcWaitTrbEnv (Private, Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = SdMmcExecTrb (Private, Trb);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Status = SdMmcWaitTrbResult (Private, Trb);\r
+ if (Status == EFI_CRC_ERROR) {\r
+ Trb->Retries--;\r
+ } else {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Sends SD command to an SD card that is attached to the SD controller.\r
\r
EFI_STATUS Status;\r
SD_MMC_HC_PRIVATE_DATA *Private;\r
SD_MMC_HC_TRB *Trb;\r
- EFI_TPL OldTpl;\r
\r
if ((This == NULL) || (Packet == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
return EFI_SUCCESS;\r
}\r
\r
- //\r
- // Wait async I/O list is empty before execute sync I/O operation.\r
- //\r
- while (TRUE) {\r
- OldTpl = gBS->RaiseTPL (TPL_NOTIFY);\r
- if (IsListEmpty (&Private->Queue)) {\r
- gBS->RestoreTPL (OldTpl);\r
- break;\r
- }\r
- gBS->RestoreTPL (OldTpl);\r
- }\r
-\r
- Status = SdMmcWaitTrbEnv (Private, Trb);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
- Status = SdMmcExecTrb (Private, Trb);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
+ Status = SdMmcPassThruExecSyncTrb (Private, Trb);\r
\r
- Status = SdMmcWaitTrbResult (Private, Trb);\r
- if (EFI_ERROR (Status)) {\r
- goto Done;\r
- }\r
-\r
-Done:\r
SdMmcFreeTrb (Trb);\r
\r
return Status;\r