diff --git a/Silicon/Hisilicon/Library/I2CLib/I2CHw.h b/Silicon/Hisilicon/Library/I2CLib/I2CHw.h
index aa561e929c..fa954c7937 100644
--- a/Silicon/Hisilicon/Library/I2CLib/I2CHw.h
+++ b/Silicon/Hisilicon/Library/I2CLib/I2CHw.h
@@ -265,5 +265,9 @@
      UINT32      Val32;
  } I2C0_ENABLE_STATUS_U;
 
+typedef enum {
+  I2CTx,
+  I2CRx
+} I2CTransfer;
 
 #endif
diff --git a/Silicon/Hisilicon/Library/I2CLib/I2CLib.c b/Silicon/Hisilicon/Library/I2CLib/I2CLib.c
index f03d55d6b2..9174e50dd4 100644
--- a/Silicon/Hisilicon/Library/I2CLib/I2CLib.c
+++ b/Silicon/Hisilicon/Library/I2CLib/I2CLib.c
@@ -238,6 +238,45 @@ I2C_GetRxStatus (
   return Fifo.bits.rxflr;
 }
 
+EFI_STATUS
+EFIAPI
+CheckI2CTimeOut (
+  UINT32      Socket,
+  UINT8       Port,
+  I2CTransfer Transfer
+  )
+{
+  UINT32 Times = 0;
+  UINT32 Fifo;
+
+  if (Transfer == I2CTx) {
+    Fifo = I2C_GetTxStatus (Socket, Port);
+    while (Fifo != 0) {
+      // This is a empirical value for I2C delay. MemoryFance is no need here.
+      I2C_Delay (2);
+      if (++Times > I2C_READ_TIMEOUT) {
+        (VOID)I2C_Disable (Socket, Port);
+        return EFI_TIMEOUT;
+      }
+      Fifo = I2C_GetTxStatus (Socket, Port);
+    }
+  } else {
+    Fifo = I2C_GetRxStatus (Socket, Port);
+    while (Fifo == 0) {
+      // This is a empirical value for I2C delay. MemoryFance is no need here.
+      I2C_Delay (2);
+      if (++Times > I2C_READ_TIMEOUT) {
+        (VOID)I2C_Disable (Socket, Port);
+        return EFI_TIMEOUT;
+      }
+      Fifo = I2C_GetRxStatus (Socket, Port);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+
 EFI_STATUS
 EFIAPI
 WriteBeforeRead (
@@ -254,15 +293,11 @@ WriteBeforeRead (
 
   I2C_SetTarget (I2cInfo->Socket, I2cInfo->Port, I2cInfo->SlaveDeviceAddress);
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  while (Fifo != 0) {
-    I2C_Delay (2);
-    if (++Times > I2C_READ_TIMEOUT) {
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
+  Fifo = 0;
   for (Count = 0; Count < Length; Count++) {
     Times = 0;
     while (Fifo > I2C_TXRX_THRESHOLD) {
@@ -277,15 +312,8 @@ WriteBeforeRead (
     Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
   }
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  Times = 0;
-  while (Fifo != 0) {
-    I2C_Delay (2);
-
-    if (++Times > I2C_READ_TIMEOUT) {
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
   return EFI_SUCCESS;
@@ -316,14 +344,8 @@ I2CWrite(
 
   I2C_SetTarget(I2cInfo->Socket, I2cInfo->Port, I2cInfo->SlaveDeviceAddress);
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  while (Fifo != 0) {
-    I2C_Delay (2);
-    if (++Times > I2C_READ_TIMEOUT) {
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
   if (I2cInfo->DeviceType) {
@@ -333,15 +355,8 @@ I2CWrite(
     I2C_REG_WRITE (Base + I2C_DATA_CMD_OFFSET, InfoOffset & 0xff);
   }
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  Times = 0;
-  while (Fifo != 0) {
-    I2C_Delay (2);
-    if (++Times > I2C_READ_TIMEOUT) {
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
   for (Idx = 0; Idx < Length; Idx++) {
@@ -364,17 +379,8 @@ I2CWrite(
     }
   }
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  Times = 0;
-  while (Fifo != 0) {
-    I2C_Delay (2);
-
-    if (++Times > I2C_READ_TIMEOUT) {
-      DEBUG ((DEBUG_ERROR, "I2C Write try to finished,time out!\n"));
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
   (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
 
@@ -390,8 +396,6 @@ I2CRead(
   UINT8 *pBuf
   )
 {
-  UINT32      Fifo;
-  UINT32      Times = 0;
   UINT8       I2CWAddr[2];
   EFI_STATUS  Status;
   UINT32      Idx = 0;
@@ -422,15 +426,8 @@ I2CRead(
 
   I2C_SetTarget (I2cInfo->Socket, I2cInfo->Port, I2cInfo->SlaveDeviceAddress);
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  while (Fifo != 0) {
-    I2C_Delay (2);
-
-    while (++Times > I2C_READ_TIMEOUT) {
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
   while (RxLen > 0) {
@@ -441,16 +438,9 @@ I2CRead(
       I2C_REG_WRITE (Base + I2C_DATA_CMD_OFFSET, I2C_READ_SIGNAL | I2C_CMD_STOP_BIT);
     }
 
-    Times = 0;
-    do {
-      I2C_Delay (2);
-
-      while (++Times > I2C_READ_TIMEOUT) {
-        (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-        return EFI_TIMEOUT;
-      }
-      Fifo = I2C_GetRxStatus (I2cInfo->Socket, I2cInfo->Port);
-    } while (Fifo == 0);
+    if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CRx) == EFI_TIMEOUT) {
+      return EFI_TIMEOUT;
+    }
 
     I2C_REG_READ (Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
 
@@ -472,8 +462,6 @@ I2CReadMultiByte (
 {
   UINT32      Count;
   UINT16      TotalLen = 0;
-  UINT32      Fifo;
-  UINT32      Times = 0;
   UINT8       I2CWAddr[4];
   EFI_STATUS  Status;
   UINT32      BytesLeft;
@@ -531,16 +519,9 @@ I2CReadMultiByte (
   }
 
   for (Count = 0; Count < BytesLeft; Count++) {
-    Times = 0;
-    do {
-      I2C_Delay (2);
-
-      while (++Times > I2C_READ_TIMEOUT) {
-        (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-        return EFI_TIMEOUT;
-      }
-      Fifo = I2C_GetRxStatus (I2cInfo->Socket, I2cInfo->Port);
-    } while (Fifo == 0);
+    if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CRx) == EFI_TIMEOUT) {
+      return EFI_TIMEOUT;
+    }
 
     I2C_REG_READ (Base + I2C_DATA_CMD_OFFSET, pBuf[Idx++]);
   }
@@ -558,8 +539,6 @@ I2CWriteMultiByte(
   UINT8      *pBuf
   )
 {
-  UINT32 Fifo;
-  UINT32 Times = 0;
   UINT32  Idx;
   UINTN  Base;
 
@@ -573,14 +552,8 @@ I2CWriteMultiByte(
 
   I2C_SetTarget(I2cInfo->Socket, I2cInfo->Port, I2cInfo->SlaveDeviceAddress);
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  while (0 != Fifo) {
-    I2C_Delay (2);
-    if (++Times > I2C_READ_TIMEOUT) {
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
 
   if (I2cInfo->DeviceType == DEVICE_TYPE_CPLD_3BYTE_OPERANDS) {
@@ -595,22 +568,12 @@ I2CWriteMultiByte(
   } else {
   }
 
-  Times = 0;
   for (Idx = 0; Idx < Length; Idx++) {
     I2C_REG_WRITE (Base + I2C_DATA_CMD_OFFSET, *pBuf++);
   }
 
-  Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
-  Times = 0;
-  while (Fifo != 0) {
-    I2C_Delay (2);
-
-    if (++Times > I2C_READ_TIMEOUT) {
-      DEBUG ((DEBUG_ERROR, "I2C Write try to finished,time out!\n"));
-      (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
-      return EFI_TIMEOUT;
-    }
-    Fifo = I2C_GetTxStatus (I2cInfo->Socket, I2cInfo->Port);
+  if (CheckI2CTimeOut (I2cInfo->Socket, I2cInfo->Port, I2CTx) == EFI_TIMEOUT) {
+    return EFI_TIMEOUT;
   }
   (VOID)I2C_Disable (I2cInfo->Socket, I2cInfo->Port);
 
