summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg
diff options
context:
space:
mode:
authorINDIA\kanagavels <kanagavels@ami.com>2024-10-17 15:37:23 +0530
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-10-28 05:39:52 +0000
commit87e2ee60d4016b6a6bd1723db1d4a76cbebfb2ee (patch)
treedf0cabc96f1039388ba99203a616338699231c8c /MdeModulePkg
parent1a3d4b33b6f1ff9a1d66e4bdf110f751ec5f9318 (diff)
downloadedk2-87e2ee60d4016b6a6bd1723db1d4a76cbebfb2ee.tar.gz
edk2-87e2ee60d4016b6a6bd1723db1d4a76cbebfb2ee.tar.bz2
edk2-87e2ee60d4016b6a6bd1723db1d4a76cbebfb2ee.zip
MdeModulePkg: Added PPI support in UFS PEI driver.
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4490 Added PPI support in UFS PEI driver to link the platform specific code as same as UFS DXE driver. Signed-off-by: Kanagavel S <kanagavels@ami.com>
Diffstat (limited to 'MdeModulePkg')
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c121
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h31
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf1
-rw-r--r--MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c108
-rw-r--r--MdeModulePkg/Include/Ppi/UfsHostControllerPlatformPpi.h97
-rw-r--r--MdeModulePkg/MdeModulePkg.dec3
6 files changed, 331 insertions, 30 deletions
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
index e04a93da6a..4c7ec648ff 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c
@@ -1082,13 +1082,17 @@ InitializeUfsBlockIoPeim (
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
- EFI_STATUS Status;
- UFS_PEIM_HC_PRIVATE_DATA *Private;
- EDKII_UFS_HOST_CONTROLLER_PPI *UfsHcPpi;
- UINT32 Index;
- UINTN MmioBase;
- UINT8 Controller;
- UFS_UNIT_DESC UnitDescriptor;
+ EFI_STATUS Status;
+ UFS_PEIM_HC_PRIVATE_DATA *Private;
+ EDKII_UFS_HOST_CONTROLLER_PPI *UfsHcPpi;
+ UINT32 Index;
+ UINTN MmioBase;
+ UINT8 Controller;
+ UFS_UNIT_DESC UnitDescriptor;
+ EDKII_UFS_HC_PLATFORM_PPI *UfsHcPlatformPpi = NULL;
+ UFS_DEV_DESC DeviceDescriptor;
+ UINT8 RefClkAttr;
+ EDKII_UFS_CARD_REF_CLK_FREQ_ATTRIBUTE Attributes;
//
// Shadow this PEIM to run from memory
@@ -1110,6 +1114,19 @@ InitializeUfsBlockIoPeim (
return EFI_DEVICE_ERROR;
}
+ //
+ // Locate ufs host controller platform PPI
+ //
+ Status = PeiServicesLocatePpi (
+ &gEdkiiUfsHcPlatformPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&UfsHcPlatformPpi
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "LocatePpi gEdkiiUfsHcPlatformPpiGuid Status :%r\n", Status));
+ }
+
IoMmuInit ();
Controller = 0;
@@ -1145,7 +1162,7 @@ InitializeUfsBlockIoPeim (
//
// Initialize UFS Host Controller H/W.
//
- Status = UfsControllerInit (Private);
+ Status = UfsControllerInit (UfsHcPlatformPpi, Private);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "UfsDevicePei: Host Controller Initialization Error, Status = %r\n", Status));
Controller++;
@@ -1174,25 +1191,87 @@ InitializeUfsBlockIoPeim (
continue;
}
- //
- // Check if 8 common luns are active and set corresponding bit mask.
- //
- for (Index = 0; Index < UFS_PEIM_MAX_LUNS; Index++) {
- Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8)Index, 0, &UnitDescriptor, sizeof (UFS_UNIT_DESC));
+ if ((UfsHcPlatformPpi != NULL) &&
+ ((UfsHcPlatformPpi->RefClkFreq == EdkiiUfsCardRefClkFreq19p2Mhz) ||
+ (UfsHcPlatformPpi->RefClkFreq == EdkiiUfsCardRefClkFreq26Mhz) ||
+ (UfsHcPlatformPpi->RefClkFreq == EdkiiUfsCardRefClkFreq38p4Mhz)))
+ {
+ RefClkAttr = UfsAttrRefClkFreq;
+ Attributes = EdkiiUfsCardRefClkFreqObsolete;
+
+ Status = UfsRwAttributes (Private, TRUE, RefClkAttr, 0, 0, (UINT32 *)&Attributes);
+ DEBUG ((DEBUG_INFO, "UfsRwAttributes #1 Status = %r \n", Status));
+ if (!EFI_ERROR (Status)) {
+ if (Attributes != UfsHcPlatformPpi->RefClkFreq) {
+ Attributes = UfsHcPlatformPpi->RefClkFreq;
+ DEBUG (
+ (DEBUG_INFO,
+ "Setting bRefClkFreq attribute(%x) to %x\n 0 -> 19.2 Mhz\n 1 -> 26 Mhz\n 2 -> 38.4 Mhz\n 3 -> Obsolete\n",
+ RefClkAttr,
+ Attributes)
+ );
+ Status = UfsRwAttributes (Private, FALSE, RefClkAttr, 0, 0, (UINT32 *)&Attributes);
+ DEBUG ((DEBUG_INFO, "UfsRwAttributes #2 Status = %r \n", Status));
+ if (EFI_ERROR (Status)) {
+ DEBUG (
+ (DEBUG_ERROR,
+ "Failed to Change Reference Clock Attribute to, Status = %r \n",
+ Status)
+ );
+ }
+ }
+ } else {
+ DEBUG (
+ (DEBUG_ERROR,
+ "Failed to Read Reference Clock Attribute, Status = %r \n",
+ Status)
+ );
+ }
+ }
+
+ if ((UfsHcPlatformPpi != NULL) && (UfsHcPlatformPpi->Callback != NULL)) {
+ Status = UfsHcPlatformPpi->Callback (&Private->UfsHcBase, EdkiiUfsHcPostLinkStartup);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Fail to read UFS Unit Descriptor, Index = %X, Status = %r\n", Index, Status));
+ DEBUG ((DEBUG_ERROR, "Failure from platform driver during EdkiiUfsHcPostLinkStartup, Status = %r\n", Status));
+ Controller++;
continue;
}
- if (UnitDescriptor.LunEn == 0x1) {
- DEBUG ((DEBUG_INFO, "Ufs %d Lun %d is enabled\n", Controller, Index));
- Private->Luns.BitMask |= (BIT0 << Index);
+ //
+ // Check if 8 common luns are active and set corresponding bit mask.
+ //
+ for (Index = 0; Index < UFS_PEIM_MAX_LUNS; Index++) {
+ Status = UfsRwDeviceDesc (Private, TRUE, UfsUnitDesc, (UINT8)Index, 0, &UnitDescriptor, sizeof (UFS_UNIT_DESC));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Fail to read UFS Unit Descriptor, Index = %X, Status = %r\n", Index, Status));
+ continue;
+ }
+
+ if (UnitDescriptor.LunEn == 0x1) {
+ DEBUG ((DEBUG_INFO, "Ufs %d Lun %d is enabled\n", Controller, Index));
+ Private->Luns.BitMask |= (BIT0 << Index);
+ }
}
- }
- PeiServicesInstallPpi (&Private->BlkIoPpiList);
- PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
- Controller++;
+ //
+ // Get Ufs Device's Lun Info by reading Configuration Descriptor
+ //
+ Status = UfsRwDeviceDesc (Private, TRUE, UfsConfigDesc, 0, 0, &DeviceDescriptor, sizeof (UFS_DEV_DESC));
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Ufs Get Configuration Descriptor Error, Status = %r\n", Status));
+ Controller++;
+ continue;
+ }
+
+ if (DeviceDescriptor.SecurityLun == 0x1) {
+ DEBUG ((DEBUG_INFO, "UFS WLUN RPMB is supported\n"));
+ Private->Luns.BitMask |= BIT11;
+ }
+
+ PeiServicesInstallPpi (&Private->BlkIoPpiList);
+ PeiServicesNotifyPpi (&Private->EndOfPeiNotifyList);
+ Controller++;
+ }
}
return EFI_SUCCESS;
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
index 869332fbe3..7815e101e2 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h
@@ -11,6 +11,7 @@
#include <PiPei.h>
#include <Ppi/UfsHostController.h>
+#include <Ppi/UfsHostControllerPlatformPpi.h>
#include <Ppi/BlockIo.h>
#include <Ppi/BlockIo2.h>
#include <Ppi/IoMmu.h>
@@ -157,6 +158,33 @@ typedef struct _UFS_DEVICE_MANAGEMENT_REQUEST_PACKET {
} UFS_DEVICE_MANAGEMENT_REQUEST_PACKET;
/**
+ Read or write specified attribute of a UFS device.
+
+ @param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
+ @param[in] Read The boolean variable to show r/w direction.
+ @param[in] AttrId The ID of Attribute.
+ @param[in] Index The Index of Attribute.
+ @param[in] Selector The Selector of Attribute.
+ @param[in, out] Attributes The value of Attribute to be read or written.
+
+ @retval EFI_SUCCESS The Attribute was read/written successfully.
+ @retval EFI_INVALID_PARAMETER AttrId, Index and Selector are invalid combination to point to a
+ type of UFS device descriptor.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the Attribute.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the Attribute.
+
+**/
+EFI_STATUS
+UfsRwAttributes (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN BOOLEAN Read,
+ IN UINT8 AttrId,
+ IN UINT8 Index,
+ IN UINT8 Selector,
+ IN OUT UINT32 *Attributes
+ );
+
+/**
Sends a UFS-supported SCSI Request Packet to a UFS device that is attached to the UFS host controller.
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
@@ -193,7 +221,8 @@ UfsExecScsiCmds (
**/
EFI_STATUS
UfsControllerInit (
- IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ IN EDKII_UFS_HC_PLATFORM_PPI *UfsHcPlatformPpi,
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
);
/**
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
index 5da906e24d..1d4850a42b 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.inf
@@ -52,6 +52,7 @@
gEdkiiPeiUfsHostControllerPpiGuid ## CONSUMES
gEdkiiIoMmuPpiGuid ## CONSUMES
gEfiEndOfPeiSignalPpiGuid ## CONSUMES
+ gEdkiiUfsHcPlatformPpiGuid ## SOMETIMES CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdUfsInitialCompletionTimeout ## CONSUMES
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
index 360b642611..88798919af 100644
--- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
+++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c
@@ -552,8 +552,8 @@ UfsCreateDMCommandDesc (
}
if (((Opcode != UtpQueryFuncOpcodeRdFlag) && (Opcode != UtpQueryFuncOpcodeSetFlag) &&
- (Opcode != UtpQueryFuncOpcodeClrFlag) && (Opcode != UtpQueryFuncOpcodeTogFlag)) &&
- ((DataSize == 0) || (Data == NULL)))
+ (Opcode != UtpQueryFuncOpcodeClrFlag) && (Opcode != UtpQueryFuncOpcodeTogFlag) &&
+ (Opcode != UtpQueryFuncOpcodeRdAttr)) && ((DataSize == 0) || (Data == NULL)))
{
return EFI_INVALID_PARAMETER;
}
@@ -759,6 +759,7 @@ UfsGetReturnDataFromQueryResponse (
)
{
UINT16 ReturnDataSize;
+ UINT32 ReturnData;
ReturnDataSize = 0;
@@ -799,6 +800,16 @@ UfsGetReturnDataFromQueryResponse (
//
*((UINT8 *)(Packet->OutDataBuffer)) = *((UINT8 *)&(QueryResp->Tsf.Value) + 3);
break;
+ case UtpQueryFuncOpcodeRdAttr:
+ ReturnData = QueryResp->Tsf.Value;
+ SwapLittleEndianToBigEndian ((UINT8 *)&ReturnData, sizeof (UINT32));
+ CopyMem (Packet->InDataBuffer, &ReturnData, sizeof (UINT32));
+ break;
+ case UtpQueryFuncOpcodeWrAttr:
+ ReturnData = QueryResp->Tsf.Value;
+ SwapLittleEndianToBigEndian ((UINT8 *)&ReturnData, sizeof (UINT32));
+ CopyMem (Packet->OutDataBuffer, &ReturnData, sizeof (UINT32));
+ break;
default:
return EFI_INVALID_PARAMETER;
}
@@ -833,7 +844,9 @@ UfsSendDmRequestRetry (
UINT8 *CmdDescBase;
UINT32 CmdDescSize;
- //
+ // Workaround: Adding this one second for reading descriptor
+ MicroSecondDelay (1 * 1000 * 1000); // delay 1 seconds
+
// Find out which slot of transfer request list is available.
//
Status = UfsFindAvailableSlotInTrl (Private, &Slot);
@@ -981,6 +994,56 @@ UfsRwDeviceDesc (
}
/**
+ Read or write specified attribute of a UFS device.
+
+ @param[in] Private The pointer to the UFS_PASS_THRU_PRIVATE_DATA data structure.
+ @param[in] Read The boolean variable to show r/w direction.
+ @param[in] AttrId The ID of Attribute.
+ @param[in] Index The Index of Attribute.
+ @param[in] Selector The Selector of Attribute.
+ @param[in, out] Attributes The value of Attribute to be read or written.
+
+ @retval EFI_SUCCESS The Attribute was read/written successfully.
+ @retval EFI_INVALID_PARAMETER AttrId, Index and Selector are invalid combination to point to a
+ type of UFS device descriptor.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to r/w the Attribute.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of r/w the Attribute.
+
+**/
+EFI_STATUS
+UfsRwAttributes (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN BOOLEAN Read,
+ IN UINT8 AttrId,
+ IN UINT8 Index,
+ IN UINT8 Selector,
+ IN OUT UINT32 *Attributes
+ )
+{
+ UFS_DEVICE_MANAGEMENT_REQUEST_PACKET Packet;
+
+ ZeroMem (&Packet, sizeof (UFS_DEVICE_MANAGEMENT_REQUEST_PACKET));
+
+ if (Read) {
+ Packet.DataDirection = UfsDataIn;
+ Packet.Opcode = UtpQueryFuncOpcodeRdAttr;
+ Packet.InDataBuffer = Attributes;
+ } else {
+ Packet.DataDirection = UfsDataOut;
+ Packet.Opcode = UtpQueryFuncOpcodeWrAttr;
+ Packet.OutDataBuffer = Attributes;
+ Packet.OutTransferLength = sizeof (UINT32);
+ }
+
+ Packet.DescId = AttrId;
+ Packet.Index = Index;
+ Packet.Selector = Selector;
+ Packet.Timeout = UFS_TIMEOUT;
+
+ return UfsSendDmRequest (Private, &Packet);
+}
+
+/**
Read or write specified flag of a UFS device.
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
@@ -1387,6 +1450,7 @@ UfsExecUicCommands (
/**
Enable the UFS host controller for accessing.
+ @param[in] UfsHcPlatformPpi The pointer to the EDKII_UFS_HC_PLATFORM_PPI data structure
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
@retval EFI_SUCCESS The UFS host controller enabling was executed successfully.
@@ -1395,13 +1459,22 @@ UfsExecUicCommands (
**/
EFI_STATUS
UfsEnableHostController (
- IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ IN EDKII_UFS_HC_PLATFORM_PPI *UfsHcPlatformPpi,
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
UINTN Address;
UINT32 Data;
+ if ((UfsHcPlatformPpi != NULL) && (UfsHcPlatformPpi->Callback != NULL)) {
+ Status = UfsHcPlatformPpi->Callback (&Private->UfsHcBase, EdkiiUfsHcPreHce);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failure from platform driver during EdkiiUfsHcPreHce, Status = %r\n", Status));
+ return Status;
+ }
+ }
+
//
// UFS 2.0 spec section 7.1.1 - Host Controller Initialization
//
@@ -1435,6 +1508,14 @@ UfsEnableHostController (
return EFI_DEVICE_ERROR;
}
+ if ((UfsHcPlatformPpi != NULL) && (UfsHcPlatformPpi->Callback != NULL)) {
+ Status = UfsHcPlatformPpi->Callback (&Private->UfsHcBase, EdkiiUfsHcPostHce);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failure from platform driver during EdkiiUfsHcPostHce, Status = %r\n", Status));
+ return Status;
+ }
+ }
+
return EFI_SUCCESS;
}
@@ -1450,7 +1531,8 @@ UfsEnableHostController (
**/
EFI_STATUS
UfsDeviceDetection (
- IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ IN EDKII_UFS_HC_PLATFORM_PPI *UfsHcPlatformPpi,
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
)
{
UINTN Retry;
@@ -1458,6 +1540,14 @@ UfsDeviceDetection (
UINT32 Data;
EFI_STATUS Status;
+ if ((UfsHcPlatformPpi != NULL) && (UfsHcPlatformPpi->Callback != NULL)) {
+ Status = UfsHcPlatformPpi->Callback (&Private->UfsHcBase, EdkiiUfsHcPreLinkStartup);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failure from platform driver during EdkiiUfsHcPreLinkStartup, Status = %r\n", Status));
+ return Status;
+ }
+ }
+
//
// Start UFS device detection.
// Try up to 3 times for establishing data link with device.
@@ -1625,6 +1715,7 @@ UfsInitTransferRequestList (
/**
Initialize the UFS host controller.
+ @param[in] UfsHcPlatformPpi The pointer to the EDKII_UFS_HC_PLATFORM_PPI data structure. // APTIOV_OVERRIDE
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
@retval EFI_SUCCESS The Ufs Host Controller is initialized successfully.
@@ -1633,18 +1724,19 @@ UfsInitTransferRequestList (
**/
EFI_STATUS
UfsControllerInit (
- IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ IN EDKII_UFS_HC_PLATFORM_PPI *UfsHcPlatformPpi,
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
)
{
EFI_STATUS Status;
- Status = UfsEnableHostController (Private);
+ Status = UfsEnableHostController (UfsHcPlatformPpi, Private);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "UfsDevicePei: Enable Host Controller Fails, Status = %r\n", Status));
return Status;
}
- Status = UfsDeviceDetection (Private);
+ Status = UfsDeviceDetection (UfsHcPlatformPpi, Private);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "UfsDevicePei: Device Detection Fails, Status = %r\n", Status));
return Status;
diff --git a/MdeModulePkg/Include/Ppi/UfsHostControllerPlatformPpi.h b/MdeModulePkg/Include/Ppi/UfsHostControllerPlatformPpi.h
new file mode 100644
index 0000000000..9384a4e4c6
--- /dev/null
+++ b/MdeModulePkg/Include/Ppi/UfsHostControllerPlatformPpi.h
@@ -0,0 +1,97 @@
+/** @file
+ EDKII_UFS_HC_PLATFORM_PPI definition.
+
+Copyright (c) 2024, American Megatrends International LLC. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _EDKII_PEI_UFS_HC_PLATFORM_PPI_H_
+#define _EDKII_PEI_UFS_HC_PLATFORM_PPI_H_
+
+#define EDKII_UFS_HC_PLATFORM_PPI_VERSION 1
+
+extern EFI_GUID gEdkiiUfsHcPlatformPpiGuid;
+
+///
+/// Forward declaration for the UFS_HOST_CONTROLLER_PPI.
+///
+typedef struct _EDKII_UFS_HC_PLATFORM_PPI EDKII_UFS_HC_PLATFORM_PPI;
+
+typedef struct {
+ UINT32 Capabilities;
+ UINT32 Version;
+} EDKII_UFS_HC_INFO;
+
+/**
+ Allows platform PPI to override host controller information
+
+ @param[in] ControllerHandle Handle of the UFS controller.
+ @param[in, out] HcInfo Pointer EDKII_UFS_HC_INFO associated with host controller.
+
+ @retval EFI_SUCCESS Function completed successfully.
+ @retval EFI_INVALID_PARAMETER HcInfo is NULL.
+ @retval Others Function failed to complete.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_UFS_HC_PLATFORM_OVERRIDE_HC_INFO)(
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EDKII_UFS_HC_INFO *HcInfo
+ );
+
+typedef enum {
+ EdkiiUfsHcPreHce,
+ EdkiiUfsHcPostHce,
+ EdkiiUfsHcPreLinkStartup,
+ EdkiiUfsHcPostLinkStartup
+} EDKII_UFS_HC_PLATFORM_CALLBACK_PHASE;
+
+typedef enum {
+ EdkiiUfsCardRefClkFreq19p2Mhz,
+ EdkiiUfsCardRefClkFreq26Mhz,
+ EdkiiUfsCardRefClkFreq38p4Mhz,
+ EdkiiUfsCardRefClkFreqObsolete
+} EDKII_UFS_CARD_REF_CLK_FREQ_ATTRIBUTE;
+
+/**
+ Callback function for platform driver.
+
+ @param[in] UfsHcBaseddr The pointer to UfsHcBase address.
+ @param[in] CallbackPhase Specifies when the platform ppi is called
+
+ @retval EFI_SUCCESS Override function completed successfully.
+ @retval EFI_INVALID_PARAMETER CallbackPhase is invalid or CallbackData is NULL when phase expects valid data.
+ @retval Others Function failed to complete.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EDKII_UFS_HC_PLATFORM_PEI_CALLBACK)(
+ IN UINTN *UfsHcBaseAddr,
+ IN EDKII_UFS_HC_PLATFORM_CALLBACK_PHASE CallbackPhase
+ );
+
+///
+/// This PPI contains a set of services to interact with the UFS host controller.
+///
+struct _EDKII_UFS_HC_PLATFORM_PPI {
+ ///
+ /// Version of the PPI.
+ ///
+ UINT32 Version;
+ ///
+ /// Allows platform driver to override host controller information.
+ ///
+ EDKII_UFS_HC_PLATFORM_OVERRIDE_HC_INFO OverrideHcInfo;
+ ///
+ /// Allows platform driver to implement platform specific flows
+ /// for host controller.
+ ///
+ EDKII_UFS_HC_PLATFORM_PEI_CALLBACK Callback;
+ ///
+ /// Reference Clock Frequency Ufs Card Attribute that need to be set in this Ufs Host Environment.
+ ///
+ EDKII_UFS_CARD_REF_CLK_FREQ_ATTRIBUTE RefClkFreq;
+};
+
+#endif
diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec
index 83e27c58aa..b9bc7041f2 100644
--- a/MdeModulePkg/MdeModulePkg.dec
+++ b/MdeModulePkg/MdeModulePkg.dec
@@ -531,6 +531,9 @@
## Include/Ppi/UfsHostController.h
gEdkiiPeiUfsHostControllerPpiGuid = { 0xdc54b283, 0x1a77, 0x4cd6, { 0x83, 0xbb, 0xfd, 0xda, 0x46, 0x9a, 0x2e, 0xc6 }}
+ ## Include/Ppi/UfsHostControllerPlatformPpi.h
+ gEdkiiUfsHcPlatformPpiGuid = { 0x9e2bde17, 0x7df0, 0x42ea, {0x98, 0xa3, 0xf6, 0x9a, 0xf3, 0xfb, 0x2b, 0xb9 }}
+
## Include/Ppi/IpmiPpi.h
gPeiIpmiPpiGuid = { 0xa9731431, 0xd968, 0x4277, { 0xb7, 0x52, 0xa3, 0xa9, 0xa6, 0xae, 0x18, 0x98 }}