diff options
author | Jason1 Lin <jason1.lin@intel.com> | 2024-07-05 22:01:00 +0800 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2024-07-17 18:03:35 +0000 |
commit | 11c50d6ca10a1410c2db187078fa7139e29e3042 (patch) | |
tree | 96d9401600a6f0dd18be8cd50282e560b06189d1 /MdeModulePkg/Bus | |
parent | 23d3fc056d37039ffe1bd4461492a1e226c779e5 (diff) | |
download | edk2-11c50d6ca10a1410c2db187078fa7139e29e3042.tar.gz edk2-11c50d6ca10a1410c2db187078fa7139e29e3042.tar.bz2 edk2-11c50d6ca10a1410c2db187078fa7139e29e3042.zip |
MdeModulePkg/UfsBlockIoPei: Wait fDeviceInit Be Cleared by Devices
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4655
[Feature Description]
- UFS device would clear fDeviceInit flag once the device initialization
is completed.
- This change is polling to check the flag is cleared or not with
specific timeout (UFS_INIT_COMPLETION_TIMEOUT - 600ms).
- This behavior is the same as UfsPassThruDxe module.
[Notes]
- This change included as a partial of below SHA1-ID
- 95ad8f7f6a6c84ef46a96a8ba852afed805d1ca3
- c5740f360636479fb91681093b1dee1cc366075c
Signed-off-by: Jason1 Lin <jason1.lin@intel.com>
Diffstat (limited to 'MdeModulePkg/Bus')
-rw-r--r-- | MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c | 60 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h | 24 | ||||
-rw-r--r-- | MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c | 28 |
3 files changed, 105 insertions, 7 deletions
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c index b8651ff998..4dbd033d41 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.c @@ -1,6 +1,6 @@ /** @file
- Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -1017,6 +1017,58 @@ UfsEndOfPei ( }
/**
+ Finishes device initialization by setting fDeviceInit flag and waiting until device responds by
+ clearing it.
+
+ @param[in] Private Pointer to the UFS_PEIM_HC_PRIVATE_DATA.
+
+ @retval EFI_SUCCESS The operation succeeds.
+ @retval Others The operation fails.
+
+**/
+EFI_STATUS
+UfsFinishDeviceInitialization (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+ UINT8 DeviceInitStatus;
+ UINT32 Timeout;
+
+ DeviceInitStatus = 0xFF;
+
+ //
+ // The host enables the device initialization completion by setting fDeviceInit flag.
+ //
+ Status = UfsSetFlag (Private, UfsFlagDevInit);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // There are cards that can take upto 600ms to clear fDeviceInit flag.
+ //
+ Timeout = UFS_INIT_COMPLETION_TIMEOUT;
+ do {
+ Status = UfsReadFlag (Private, UfsFlagDevInit, &DeviceInitStatus);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MicroSecondDelay (1);
+ Timeout--;
+ } while (DeviceInitStatus != 0 && Timeout != 0);
+
+ if (Timeout == 0) {
+ DEBUG ((DEBUG_ERROR, "%a: DeviceInitStatus = %x EFI_TIMEOUT \n", __func__, DeviceInitStatus));
+ return EFI_TIMEOUT;
+ } else {
+ DEBUG ((DEBUG_INFO, "%a: Timeout left = %x EFI_SUCCESS \n", __func__, Timeout));
+ return EFI_SUCCESS;
+ }
+}
+
+/**
The user code starts with this function.
@param FileHandle Handle of the file being invoked.
@@ -1116,11 +1168,11 @@ InitializeUfsBlockIoPeim ( }
//
- // The host enables the device initialization completion by setting fDeviceInit flag.
+ // Check the UFS device is initialized completed.
//
- Status = UfsSetFlag (Private, UfsFlagDevInit);
+ Status = UfsFinishDeviceInitialization (Private);
if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "Ufs Set fDeviceInit Flag Error, Status = %r\n", Status));
+ DEBUG ((DEBUG_ERROR, "Device failed to finish initialization, Status = %r\n", Status));
Controller++;
continue;
}
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h index ed4776f548..489b6c34ec 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsBlockIoPei.h @@ -1,6 +1,6 @@ /** @file
- Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -31,7 +31,8 @@ #define UFS_PEIM_HC_SIG SIGNATURE_32 ('U', 'F', 'S', 'H')
-#define UFS_PEIM_MAX_LUNS 8
+#define UFS_PEIM_MAX_LUNS 8
+#define UFS_INIT_COMPLETION_TIMEOUT 600000
typedef struct {
UINT8 Lun[UFS_PEIM_MAX_LUNS];
@@ -227,6 +228,25 @@ UfsSetFlag ( );
/**
+ Read specified flag from a UFS device.
+
+ @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
+ @param[in] FlagId The ID of flag to be read.
+ @param[out] Value The flag's value.
+
+ @retval EFI_SUCCESS The flag was read successfully.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag.
+
+**/
+EFI_STATUS
+UfsReadFlag (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN UINT8 FlagId,
+ OUT UINT8 *Value
+ );
+
+/**
Read or write specified device descriptor of a UFS device.
@param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
diff --git a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c index d19a7fed6e..360b642611 100644 --- a/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c +++ b/MdeModulePkg/Bus/Ufs/UfsBlockIoPei/UfsHci.c @@ -1,6 +1,6 @@ /** @file
- Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2014 - 2024, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -1066,6 +1066,32 @@ UfsSetFlag ( }
/**
+ Read specified flag from a UFS device.
+
+ @param[in] Private The pointer to the UFS_PEIM_HC_PRIVATE_DATA data structure.
+ @param[in] FlagId The ID of flag to be read.
+ @param[out] Value The flag's value.
+
+ @retval EFI_SUCCESS The flag was read successfully.
+ @retval EFI_DEVICE_ERROR A device error occurred while attempting to read the flag.
+ @retval EFI_TIMEOUT A timeout occurred while waiting for the completion of reading the flag.
+
+**/
+EFI_STATUS
+UfsReadFlag (
+ IN UFS_PEIM_HC_PRIVATE_DATA *Private,
+ IN UINT8 FlagId,
+ OUT UINT8 *Value
+ )
+{
+ EFI_STATUS Status;
+
+ Status = UfsRwFlags (Private, TRUE, FlagId, Value);
+
+ return Status;
+}
+
+/**
Sends NOP IN cmd to a UFS device for initialization process request.
For more details, please refer to UFS 2.0 spec Figure 13.3.
|