瀏覽代碼

MdeModulePkg: Add bRefClkFreq card attribute programming support

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3851

When the UFS card comes out of Manufacturer, bRefClkFreq attribute is set
to 1h on the UFS card as per the Manufacturer Default Value
specified by the spec JESD220*. However, depends on the UFS host system
environment, it need to be set to the correct value.

Reference Clock Frequency value
0h:19.2 MHz
1h: 26 MHz
2h: 38.4 MHz
3h: Obsolete
Others: Reserved

Cc: Wu Hao A <hao.a.wu@intel.com>
Cc: Albecki Mateusz <mateusz.albecki@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>

Signed-off-by: Purna Chandra Rao Bandaru <purna.chandra.rao.bandaru@intel.com>
Reviewed-by: Hao A Wu <hao.a.wu@intel.com>
Bandaru, Purna Chandra Rao 2 年之前
父節點
當前提交
f06941cc46

+ 60 - 10
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThru.c

@@ -1,6 +1,6 @@
 /** @file
 
-  Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
   Copyright (c) Microsoft Corporation.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -834,15 +834,17 @@ UfsPassThruDriverBindingStart (
   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
   )
 {
-  EFI_STATUS                          Status;
-  EDKII_UFS_HOST_CONTROLLER_PROTOCOL  *UfsHc;
-  UFS_PASS_THRU_PRIVATE_DATA          *Private;
-  UINTN                               UfsHcBase;
-  UINT32                              Index;
-  UFS_UNIT_DESC                       UnitDescriptor;
-  UFS_DEV_DESC                        DeviceDescriptor;
-  UINT32                              UnitDescriptorSize;
-  UINT32                              DeviceDescriptorSize;
+  EFI_STATUS                             Status;
+  EDKII_UFS_HOST_CONTROLLER_PROTOCOL     *UfsHc;
+  UFS_PASS_THRU_PRIVATE_DATA             *Private;
+  UINTN                                  UfsHcBase;
+  UINT32                                 Index;
+  UFS_UNIT_DESC                          UnitDescriptor;
+  UFS_DEV_DESC                           DeviceDescriptor;
+  UINT32                                 UnitDescriptorSize;
+  UINT32                                 DeviceDescriptorSize;
+  EDKII_UFS_CARD_REF_CLK_FREQ_ATTRIBUTE  Attributes;
+  UINT8                                  RefClkAttr;
 
   Status    = EFI_SUCCESS;
   UfsHc     = NULL;
@@ -917,6 +919,54 @@ UfsPassThruDriverBindingStart (
     goto Error;
   }
 
+  if ((mUfsHcPlatform != NULL) &&
+      ((mUfsHcPlatform->RefClkFreq == EdkiiUfsCardRefClkFreq19p2Mhz) ||
+       (mUfsHcPlatform->RefClkFreq == EdkiiUfsCardRefClkFreq26Mhz) ||
+       (mUfsHcPlatform->RefClkFreq == EdkiiUfsCardRefClkFreq38p4Mhz)))
+  {
+    RefClkAttr = UfsAttrRefClkFreq;
+    Attributes = EdkiiUfsCardRefClkFreqObsolete;
+    Status     = UfsRwAttributes (Private, TRUE, RefClkAttr, 0, 0, (UINT32 *)&Attributes);
+    if (!EFI_ERROR (Status)) {
+      if (Attributes != mUfsHcPlatform->RefClkFreq) {
+        Attributes = mUfsHcPlatform->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);
+        if (EFI_ERROR (Status)) {
+          DEBUG (
+            (DEBUG_ERROR,
+             "Failed to Change Reference Clock Attribute to %d, Status = %r \n",
+             mUfsHcPlatform->RefClkFreq,
+             Status)
+            );
+        }
+      }
+    } else {
+      DEBUG (
+        (DEBUG_ERROR,
+         "Failed to Read Reference Clock Attribute, Status = %r \n",
+         Status)
+        );
+    }
+  }
+
+  if ((mUfsHcPlatform != NULL) && (mUfsHcPlatform->Callback != NULL)) {
+    Status = mUfsHcPlatform->Callback (Private->Handle, EdkiiUfsHcPostLinkStartup, &Private->UfsHcDriverInterface);
+    if (EFI_ERROR (Status)) {
+      DEBUG (
+        (DEBUG_ERROR,
+         "Failure from platform driver during EdkiiUfsHcPostLinkStartup, Status = %r\n",
+         Status)
+        );
+      return Status;
+    }
+  }
+
   //
   // UFS 2.0 spec Section 13.1.3.3:
   // At the end of the UFS Interconnect Layer initialization on both host and device side,

+ 1 - 9
MdeModulePkg/Bus/Ufs/UfsPassThruDxe/UfsPassThruHci.c

@@ -2,7 +2,7 @@
   UfsPassThruDxe driver is used to produce EFI_EXT_SCSI_PASS_THRU protocol interface
   for upper layer application to execute UFS-supported SCSI cmds.
 
-  Copyright (c) 2014 - 2019, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2014 - 2022, Intel Corporation. All rights reserved.<BR>
   Copyright (c) Microsoft Corporation.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -1970,14 +1970,6 @@ UfsDeviceDetection (
         return EFI_DEVICE_ERROR;
       }
     } else {
-      if ((mUfsHcPlatform != NULL) && (mUfsHcPlatform->Callback != NULL)) {
-        Status = mUfsHcPlatform->Callback (Private->Handle, EdkiiUfsHcPostLinkStartup, &Private->UfsHcDriverInterface);
-        if (EFI_ERROR (Status)) {
-          DEBUG ((DEBUG_ERROR, "Failure from platform driver during EdkiiUfsHcPostLinkStartup, Status = %r\n", Status));
-          return Status;
-        }
-      }
-
       return EFI_SUCCESS;
     }
   }

+ 13 - 2
MdeModulePkg/Include/Protocol/UfsHostControllerPlatform.h

@@ -1,7 +1,7 @@
 /** @file
   EDKII_UFS_HC_PLATFORM_PROTOCOL definition.
 
-Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2019 - 2022, Intel Corporation. All rights reserved.<BR>
 SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -11,7 +11,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include <Protocol/UfsHostController.h>
 
-#define EDKII_UFS_HC_PLATFORM_PROTOCOL_VERSION  1
+#define EDKII_UFS_HC_PLATFORM_PROTOCOL_VERSION  2
 
 extern EFI_GUID  gEdkiiUfsHcPlatformProtocolGuid;
 
@@ -83,6 +83,13 @@ typedef enum {
   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.
 
@@ -118,6 +125,10 @@ struct _EDKII_UFS_HC_PLATFORM_PROTOCOL {
   /// for host controller.
   ///
   EDKII_UFS_HC_PLATFORM_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