[edk2] [Patch][edk2-platforms/devel-MinnowBoard3-UDK2017 06/1BroxtonSiPkg: Add I2CLibPei

Guo, Mang posted 1 patch 6 years, 7 months ago
Failed in applying to current master (apply log)
.../PlatformDsc/Components.IA32.dsc                |   1 +
.../SouthCluster/Include/Library/I2CLib.h          | 106 +---
.../SouthCluster/Include/ScRegs/RegsI2c.h          | 143 +++++
.../SouthCluster/Library/I2CLibPei/I2CAccess.h     |  51 ++
.../SouthCluster/Library/I2CLibPei/I2CDelayPei.c   |  49 ++
.../SouthCluster/Library/I2CLibPei/I2CDelayPei.h   |  34 ++
.../SouthCluster/Library/I2CLibPei/I2CIoLibPei.c   | 175 ++++++
.../SouthCluster/Library/I2CLibPei/I2CIoLibPei.h   | 146 +++++
.../SouthCluster/Library/I2CLibPei/I2CLibPei.c     | 665 +++++++++++++++++++++
.../SouthCluster/Library/I2CLibPei/I2CLibPei.inf   |  51 ++
10 files changed, 1322 insertions(+), 99 deletions(-)
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CAccess.h
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.c
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.h
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.c
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.h
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.inf
[edk2] [Patch][edk2-platforms/devel-MinnowBoard3-UDK2017 06/1BroxtonSiPkg: Add I2CLibPei
Posted by Guo, Mang 6 years, 7 months ago
Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Guo Mang <mang.guo@intel.com>
---
 .../PlatformDsc/Components.IA32.dsc                |   1 +
 .../SouthCluster/Include/Library/I2CLib.h          | 106 +---
 .../SouthCluster/Include/ScRegs/RegsI2c.h          | 143 +++++
 .../SouthCluster/Library/I2CLibPei/I2CAccess.h     |  51 ++
 .../SouthCluster/Library/I2CLibPei/I2CDelayPei.c   |  49 ++
 .../SouthCluster/Library/I2CLibPei/I2CDelayPei.h   |  34 ++
 .../SouthCluster/Library/I2CLibPei/I2CIoLibPei.c   | 175 ++++++
 .../SouthCluster/Library/I2CLibPei/I2CIoLibPei.h   | 146 +++++
 .../SouthCluster/Library/I2CLibPei/I2CLibPei.c     | 665 +++++++++++++++++++++
 .../SouthCluster/Library/I2CLibPei/I2CLibPei.inf   |  51 ++
 10 files changed, 1322 insertions(+), 99 deletions(-)
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CAccess.h
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.c
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.h
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.c
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.h
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.inf

diff --git a/Platform/BroxtonPlatformPkg/PlatformDsc/Components.IA32.dsc b/Platform/BroxtonPlatformPkg/PlatformDsc/Components.IA32.dsc
index f8900ea..cdbba2a 100644
--- a/Platform/BroxtonPlatformPkg/PlatformDsc/Components.IA32.dsc
+++ b/Platform/BroxtonPlatformPkg/PlatformDsc/Components.IA32.dsc
@@ -116,6 +116,7 @@
        NULL|$(PLATFORM_NAME)/Board/MinnowBoard3/BoardInitPostMem/BoardInitPostMem.inf
        NULL|$(PLATFORM_NAME)/Board/LeafHill/BoardInitPostMem/BoardInitPostMem.inf
        NULL|$(PLATFORM_NAME)/Board/BensonGlacier/BoardInitPostMem/BoardInitPostMem.inf
+       I2cLibPei|$(PLATFORM_SI_PACKAGE)/SouthCluster/Library/I2CLibPei/I2CLibPei.inf
     <PcdsPatchableInModule>
       gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x803805c6
   }
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h
index b593620..b897cb9 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h
@@ -1,7 +1,7 @@
 /** @file
   Register Definitions for I2C Library.
 
-  Copyright (c) 1999 - 2016, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
 
   This program and the accompanying materials
   are licensed and made available under the terms and conditions of the BSD License
@@ -18,111 +18,19 @@
 
 #include <Uefi.h>
 #include <Library/IoLib.h>
-
 //
 // FIFO write workaround value.
 //
 #define FIFO_WRITE_DELAY    2
 
-//
-// MMIO Register Definitions
-//
-#define    R_IC_CON                          (0x00)  ///< I2C Control
-#define    B_IC_RESTART_EN                  BIT5
-#define    B_IC_SLAVE_DISABLE               BIT6
-#define    V_SPEED_STANDARD                 0x02
-#define    V_SPEED_FAST                     0x04
-#define    V_SPEED_HIGH                     0x06
-#define    B_MASTER_MODE                    BIT0
-
-#define    R_IC_TAR                         (0x04)  ///< I2C Target Address
-#define    IC_TAR_10BITADDR_MASTER          BIT12
-
-#define    R_IC_SAR                         (0x08)  ///< I2C Slave Address
-#define    R_IC_HS_MADDR                    (0x0C)  ///< I2C HS MasterMode Code Address
-#define    R_IC_DATA_CMD                    (0x10)  ///< I2C Rx/Tx Data Buffer and Command
-
-#define    B_READ_CMD                        BIT8   ///< 1 = read, 0 = write
-#define    B_CMD_STOP                        BIT9   ///< 1 = STOP
-#define    B_CMD_RESTART                     BIT10  ///< 1 = IC_RESTART_EN
-
-#define    V_WRITE_CMD_MASK                  (0xFF)
-
-#define    R_IC_SS_SCL_HCNT                  (0x14)  ///< Standard Speed I2C Clock SCL High Count
-#define    R_IC_SS_SCL_LCNT                  (0x18)  ///< Standard Speed I2C Clock SCL Low Count
-#define    R_IC_FS_SCL_HCNT                  (0x1C)  ///< Full Speed I2C Clock SCL High Count
-#define    R_IC_FS_SCL_LCNT                  (0x20)  ///< Full Speed I2C Clock SCL Low Count
-#define    R_IC_HS_SCL_HCNT                  (0x24)  ///< High Speed I2C Clock SCL High Count
-#define    R_IC_HS_SCL_LCNT                  (0x28)  ///< High Speed I2C Clock SCL Low Count
-#define    R_IC_INTR_STAT                    (0x2C)  ///< I2C Inetrrupt Status
-#define    R_IC_INTR_MASK                    (0x30)  ///< I2C Interrupt Mask
-#define    I2C_INTR_GEN_CALL                 BIT11   ///< General call received
-#define    I2C_INTR_START_DET                BIT10
-#define    I2C_INTR_STOP_DET                 BIT9
-#define    I2C_INTR_ACTIVITY                 BIT8
-#define    I2C_INTR_TX_ABRT                  BIT6    ///< Set on NACK
-#define    I2C_INTR_TX_EMPTY                 BIT4
-#define    I2C_INTR_TX_OVER                  BIT3
-#define    I2C_INTR_RX_FULL                  BIT2    ///< Data bytes in RX FIFO over threshold
-#define    I2C_INTR_RX_OVER                  BIT1
-#define    I2C_INTR_RX_UNDER                 BIT0
-#define    R_IC_RAW_INTR_STAT                (0x34)  ///< I2C Raw Interrupt Status
-#define    R_IC_RX_TL                        (0x38)  ///< I2C Receive FIFO Threshold
-#define    R_IC_TX_TL                        (0x3C)  ///< I2C Transmit FIFO Threshold
-#define    R_IC_CLR_INTR                     (0x40)  ///< Clear Combined and Individual Interrupts
-#define    R_IC_CLR_RX_UNDER                 (0x44)  ///< Clear RX_UNDER Interrupt
-#define    R_IC_CLR_RX_OVER                  (0x48)  ///< Clear RX_OVERinterrupt
-#define    R_IC_CLR_TX_OVER                  (0x4C)  ///< Clear TX_OVER interrupt
-#define    R_IC_CLR_RD_REQ                   (0x50)  ///< Clear RD_REQ interrupt
-#define    R_IC_CLR_TX_ABRT                  (0x54)  ///< Clear TX_ABRT interrupt
-#define    R_IC_CLR_RX_DONE                  (0x58)  ///< Clear RX_DONE interrupt
-#define    R_IC_CLR_ACTIVITY                 (0x5C)  ///< Clear ACTIVITY interrupt
-#define    R_IC_CLR_STOP_DET                 (0x60)  ///< Clear STOP_DET interrupt
-#define    R_IC_CLR_START_DET                (0x64)  ///< Clear START_DET interrupt
-#define    R_IC_CLR_GEN_CALL                 (0x68)  ///< Clear GEN_CALL interrupt
-#define    R_IC_ENABLE                       (0x6C)  ///< I2C Enable
-#define    R_IC_STATUS                       (0x70)  ///< I2C Status
-
-#define    R_IC_SDA_HOLD                     (0x7C)  ///< I2C IC_DEFAULT_SDA_HOLD//16bits
-
-#define    STAT_MST_ACTIVITY                 BIT5   ///< Master FSM Activity Status.
-#define    STAT_RFF                          BIT4   ///< RX FIFO is completely full
-#define    STAT_RFNE                         BIT3   ///< RX FIFO is not empty
-#define    STAT_TFE                          BIT2   ///< TX FIFO is completely empty
-#define    STAT_TFNF                         BIT1   ///< TX FIFO is not full
-
-#define    R_IC_TXFLR                        (0x74)  ///< Transmit FIFO Level Register
-#define    R_IC_RXFLR                        (0x78)  ///< Receive FIFO Level Register
-#define    R_IC_TX_ABRT_SOURCE               (0x80)  ///< I2C Transmit Abort Status Register
-#define    R_IC_SLV_DATA_NACK_ONLY           (0x84)  ///< Generate SLV_DATA_NACK Register
-#define    R_IC_DMA_CR                       (0x88)  ///< DMA Control Register
-#define    R_IC_DMA_TDLR                     (0x8C)  ///< DMA Transmit Data Level
-#define    R_IC_DMA_RDLR                     (0x90)  ///< DMA Receive Data Level
-#define    R_IC_SDA_SETUP                    (0x94)  ///< I2C SDA Setup Register
-#define    R_IC_ACK_GENERAL_CALL             (0x98)  ///< I2C ACK General Call Register
-#define    R_IC_ENABLE_STATUS                (0x9C)  ///< I2C Enable Status Register
-#define    R_IC_COMP_PARAM                   (0xF4)  ///< Component Parameter Register
-#define    R_IC_COMP_VERSION                 (0xF8)  ///< Component Version ID
-#define    R_IC_COMP_TYPE                    (0xFC)  ///< Component Type
-
-#define    R_IC_CLK_GATE                     (0xC0)  ///< Clock Gate
-
-#define     IC_TAR_10BITADDR_MASTER           BIT12
-#define     FIFO_SIZE                         32
-
-
 /**
   Program LPSS I2C PCI controller's BAR0 and enable memory decode.
 
-  @param[in]  BusNo                 I2C Bus number to which the I2C device has been connected
-
-  @retval     EFI_SUCCESS           I2C controller's BAR0 is programmed and memory decode enabled.
-  @retval     EFI_NOT_READY         I2C controller's is not exist or its function has been disabled.
-
+  @retval EFI_SUCCESS           - I2C controller's BAR0 is programmed and memory decode enabled.
 **/
 EFI_STATUS
 ProgramPciLpssI2C (
-  IN UINT8        BusNo
+  VOID
   );
 
 /**
@@ -130,7 +38,7 @@ ProgramPciLpssI2C (
   This is actual I2C hardware operation function.
 
   @param[in]  BusNo                 I2C Bus number to which the I2C device has been connected
-  @param[in]  SlaveAddress          Slave address of the I2C device
+  @param[in]  SlaveAddress          Slave address of the I2C device (7-bit)
   @param[in]  ReadBytes             Number of bytes to be read
   @param[out] ReadBuffer            Address to which the value read has to be stored
   @param[in]  Start                 It controls whether a RESTART is issued before the byte is sent or received.
@@ -157,7 +65,7 @@ ByteReadI2C_Basic (
   This is actual I2C hardware operation function.
 
   @param[in]  BusNo                 I2C Bus number to which the I2C device has been connected
-  @param[in]  SlaveAddress          Slave address of the I2C device
+  @param[in]  SlaveAddress          Slave address of the I2C device (7-bit)
   @param[in]  WriteBytes            Number of bytes to be written
   @param[in]  WriteBuffer           Address to which the byte value has to be written
   @param[in]  Start                 It controls whether a RESTART is issued before the byte is sent or received.
@@ -183,7 +91,7 @@ ByteWriteI2C_Basic (
   Read bytes from I2C Device
 
   @param[in]  BusNo               I2C Bus number to which the I2C device has been connected
-  @param[in]  SlaveAddress        Slave address of the I2C device
+  @param[in]  SlaveAddress        Slave address of the I2C device (7-bit)
   @param[in]  Offset              Register offset from which the data has to be read
   @param[in]  ReadBytes           Number of bytes to be read
   @param[out] ReadBuffer          Address to which the value read has to be stored
@@ -205,7 +113,7 @@ ByteReadI2C (
   Write bytes to I2C Device
 
   @param[in]  BusNo               I2C Bus number to which the I2C device has been connected
-  @param[in]  SlaveAddress        Slave address of the I2C device
+  @param[in]  SlaveAddress        Slave address of the I2C device (7-bit)
   @param[in]  Offset              Register offset from which the data has to be read
   @param[in]  WriteBytes          Number of bytes to be written
   @param[in]  WriteBuffer         Address to which the byte value has to be written
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
new file mode 100644
index 0000000..5fc758d
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
@@ -0,0 +1,143 @@
+/** @file
+  Register names for I2C device.
+
+  Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _REGS_I2C_H_
+#define _REGS_I2C_H_
+
+#define    DEFAULT_PCI_BUS_NUMBER_SC         0
+#define    PCI_DEVICE_NUMBER_LPSS_I2C        30
+
+#define    R_LPSS_I2C_STSCMD                 0x04  ///< Status & Command
+#define    B_LPSS_I2C_STSCMD_RMA             BIT29 ///< RMA
+#define    B_LPSS_I2C_STSCMD_RCA             BIT28 ///< RCA
+#define    B_LPSS_I2C_STSCMD_CAPLIST         BIT20 ///< Capability List
+#define    B_LPSS_I2C_STSCMD_INTRSTS         BIT19 ///< Interrupt Status
+#define    B_LPSS_I2C_STSCMD_INTRDIS         BIT10 ///< Interrupt Disable
+#define    B_LPSS_I2C_STSCMD_SERREN          BIT8  ///< SERR# Enable
+#define    B_LPSS_I2C_STSCMD_BME             BIT2  ///< Bus Master Enable
+#define    B_LPSS_I2C_STSCMD_MSE             BIT1  ///< Memory Space Enable
+
+#define    R_LPSS_I2C_BAR                    0x10  ///< BAR0 Low
+#define    B_LPSS_I2C_BAR_BA                 0xFFFFF000 ///< Base Address
+#define    B_LPSS_I2C_BAR_SI                 0x00000FF0 ///< Size Indicator
+#define    B_LPSS_I2C_BAR_PF                 BIT3  ///< Prefetchable
+#define    B_LPSS_I2C_BAR_TYPE               (BIT2 | BIT1) ///< Type
+#define    B_LPSS_I2C_BAR_MS                 BIT0  ///< Message Space
+
+#define    R_LPSS_I2C_BAR1                   0x18  ///< BAR1 Low
+#define    B_LPSS_I2C_BAR1_BA                0xFFFFF000 ///< Base Address
+#define    B_LPSS_I2C_BAR1_SI                0x00000FF0 ///< Size Indicator
+#define    B_LPSS_I2C_BAR1_PF                BIT3  ///< Prefetchable
+#define    B_LPSS_I2C_BAR1_TYPE              (BIT2 | BIT1) ///< Type
+#define    B_LPSS_I2C_BAR1_MS                BIT0  ///< Message Space
+
+#define    NUM_RETRIES                       0xFFFF
+
+#define    bit(a)                            1 << (a)
+
+///
+/// MMI/O Register Definitions
+///
+#define    I2C0_REG_SPACE_ADDR_BASE          0xFF138000  ///< 01K
+
+#define    R_IC_CON                          (0x00) ///< I2C Control
+#define    B_IC_RESTART_EN                   BIT5
+#define    B_IC_SLAVE_DISABLE                BIT6
+#define    V_SPEED_STANDARD                  0x02
+#define    V_SPEED_FAST                      0x04
+#define    V_SPEED_HIGH                      0x06
+#define    B_MASTER_MODE                     BIT0
+
+#define    R_IC_TAR                          (0x04) ///< I2C Target Address
+#define    IC_TAR_10BITADDR_MASTER           BIT12
+
+#define    R_IC_SAR                          (0x08) ///< I2C Slave Address
+#define    R_IC_HS_MADDR                     (0x0C) ///< I2C HS MasterMode Code Address
+#define    R_IC_DATA_CMD                     (0x10) ///< I2C Rx/Tx Data Buffer and Command
+
+#define    B_READ_CMD                         BIT8  ///< 1 = read, 0 = write
+#define    B_CMD_STOP                         BIT9  ///< 1 = STOP
+#define    B_CMD_RESTART                      BIT10 ///< 1 = IC_RESTART_EN
+
+#define    V_WRITE_CMD_MASK                  (0xFF)
+
+#define    R_IC_SS_SCL_HCNT                  (0x14) ///< Standard Speed I2C Clock SCL High Count
+#define    R_IC_SS_SCL_LCNT                  (0x18) ///< Standard Speed I2C Clock SCL Low Count
+#define    R_IC_FS_SCL_HCNT                  (0x1C) ///< Full Speed I2C Clock SCL High Count
+#define    R_IC_FS_SCL_LCNT                  (0x20) ///< Full Speed I2C Clock SCL Low Count
+#define    R_IC_HS_SCL_HCNT                  (0x24) ///< High Speed I2C Clock SCL High Count
+#define    R_IC_HS_SCL_LCNT                  (0x28) ///< High Speed I2C Clock SCL Low Count
+#define    R_IC_INTR_STAT                    (0x2C) ///< I2C Inetrrupt Status
+#define    R_IC_INTR_MASK                    (0x30) ///< I2C Interrupt Mask
+#define    I2C_INTR_GEN_CALL                 BIT11 ///< General call received
+#define    I2C_INTR_START_DET                BIT10
+#define    I2C_INTR_STOP_DET                 BIT9
+#define    I2C_INTR_ACTIVITY                 BIT8
+#define    I2C_INTR_TX_ABRT                  BIT6  ///< Set on NACK
+#define    I2C_INTR_TX_EMPTY                 BIT4
+#define    I2C_INTR_TX_OVER                  BIT3
+#define    I2C_INTR_RX_FULL                  BIT2  ///< Data bytes in RX FIFO over threshold
+#define    I2C_INTR_RX_OVER                  BIT1
+#define    I2C_INTR_RX_UNDER                 BIT0
+#define    R_IC_RAW_INTR_STAT                (0x34) ///< I2C Raw Interrupt Status
+#define    R_IC_RX_TL                        (0x38) ///< I2C Receive FIFO Threshold
+#define    R_IC_TX_TL                        (0x3C) ///< I2C Transmit FIFO Threshold
+#define    R_IC_CLR_INTR                     (0x40) ///< Clear Combined and Individual Interrupts
+#define    R_IC_CLR_RX_UNDER                 (0x44) ///< Clear RX_UNDER Interrupt
+#define    R_IC_CLR_RX_OVER                  (0x48) ///< Clear RX_OVERinterrupt
+#define    R_IC_CLR_TX_OVER                  (0x4C) ///< Clear TX_OVER interrupt
+#define    R_IC_CLR_RD_REQ                   (0x50) ///< Clear RD_REQ interrupt
+#define    R_IC_CLR_TX_ABRT                  (0x54) ///< Clear TX_ABRT interrupt
+#define    R_IC_CLR_RX_DONE                  (0x58) ///< Clear RX_DONE interrupt
+#define    R_IC_CLR_ACTIVITY                 (0x5C) ///< Clear ACTIVITY interrupt
+#define    R_IC_CLR_STOP_DET                 (0x60) ///< Clear STOP_DET interrupt
+#define    R_IC_CLR_START_DET                (0x64) ///< Clear START_DET interrupt
+#define    R_IC_CLR_GEN_CALL                 (0x68) ///< Clear GEN_CALL interrupt
+#define    R_IC_ENABLE                       (0x6C) ///< I2C Enable
+#define    R_IC_STATUS                       (0x70) ///< I2C Status
+
+#define    R_IC_SDA_HOLD                     (0x7C) ///< I2C IC_DEFAULT_SDA_HOLD//16bits
+
+#define    STAT_MST_ACTIVITY                 BIT5  ///< Master FSM Activity Status.
+#define    STAT_RFF                          BIT4  ///< RX FIFO is completely full
+#define    STAT_RFNE                         BIT3  ///< RX FIFO is not empty
+#define    STAT_TFE                          BIT2  ///< TX FIFO is completely empty
+#define    STAT_TFNF                         BIT1  ///< TX FIFO is not full
+
+#define    R_IC_TXFLR                        (0x74) ///< Transmit FIFO Level Register
+#define    R_IC_RXFLR                        (0x78) ///< Receive FIFO Level Register
+#define    R_IC_TX_ABRT_SOURCE               (0x80) ///< I2C Transmit Abort Status Register
+#define    R_IC_SLV_DATA_NACK_ONLY           (0x84) ///< Generate SLV_DATA_NACK Register
+#define    R_IC_DMA_CR                       (0x88) ///< DMA Control Register
+#define    R_IC_DMA_TDLR                     (0x8C) ///< DMA Transmit Data Level
+#define    R_IC_DMA_RDLR                     (0x90) ///< DMA Receive Data Level
+#define    R_IC_SDA_SETUP                    (0x94) ///< I2C SDA Setup Register
+#define    R_IC_ACK_GENERAL_CALL             (0x98) ///< I2C ACK General Call Register
+#define    R_IC_ENABLE_STATUS                (0x9C) ///< I2C Enable Status Register
+#define    R_IC_COMP_PARAM                   (0xF4) ///< Component Parameter Register
+#define    R_IC_COMP_VERSION                 (0xF8) ///< Component Version ID
+#define    R_IC_COMP_TYPE                    (0xFC) ///< Component Type
+
+#define    R_IC_CLK_GATE                     (0xC0) ///< Clock Gate
+
+#define    I2C_SS_SCL_HCNT_VALUE_100M         0x1DD
+#define    I2C_SS_SCL_LCNT_VALUE_100M         0x1E4
+#define    I2C_FS_SCL_HCNT_VALUE_100M         0x54
+#define    I2C_FS_SCL_LCNT_VALUE_100M         0x9a
+#define    I2C_HS_SCL_HCNT_VALUE_100M         0x7
+#define    I2C_HS_SCL_LCNT_VALUE_100M         0xE
+
+#endif
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CAccess.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CAccess.h
new file mode 100644
index 0000000..792a483
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CAccess.h
@@ -0,0 +1,51 @@
+
+/** @file
+  Macros that simplify accessing I2C device's registers.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _I2C_ACCESS_H_
+#define _I2C_ACCESS_H_
+
+///
+/// Memory Mapped PCI Access macros
+///
+
+#include "I2CIoLibPei.h"
+
+#define DEFAULT_PCI_BUS_NUMBER_SC   0
+
+#define PCI_DEVICE_NUMBER_LPC       31
+#define PCI_FUNCTION_NUMBER_LPC     0
+
+#define R_LPC_ACPI_BASE             0x40        ///< ABASE, 16bit
+#define R_LPC_ACPI_BASEADR          0x400       ///< ABASE, 16bit
+#define B_LPC_ACPI_BASE_EN          BIT1        ///< Enable Bit
+#define B_LPC_ACPI_BASE_BAR         0x0000FF80  ///< Base Address, 128 Bytes
+#define V_ACPI_PM1_TMR_MAX_VAL      0x1000000   ///< The timer is 24 bit overflow
+#define B_ACPI_PM1_TMR_VAL          0xFFFFFF    ///< The timer value mask
+
+#define R_ACPI_PM1_TMR              0x08        ///< Power Management 1 Timer
+#define V_ACPI_PM1_TMR_FREQUENCY    3579545     ///< Timer Frequency
+
+
+#define ScLpcPciCfg8(Register)      I2CLibPeiMmioRead8 (MmPciAddress (0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPC, 0, Register))
+
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)PcdGet64 (PcdPciExpressBaseAddress)+ \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+#endif
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.c
new file mode 100644
index 0000000..409376a
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.c
@@ -0,0 +1,49 @@
+/** @file
+  Timer instance for I2C Pei Library.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include "I2CAccess.h"
+#include "I2CDelayPei.h"
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Ppi/Stall.h>
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  @param[in]  MicroSeconds     The minimum number of microseconds to delay.
+
+  @retval  EFI_SUCCESS         Time delay successfully
+**/
+EFI_STATUS
+EFIAPI
+MicroSecondDelay (
+  IN UINTN                     MicroSeconds
+  )
+{
+  EFI_PEI_STALL_PPI              *StallPpi;
+  EFI_STATUS                     Status;
+  CONST EFI_PEI_SERVICES         **PeiServices;
+
+  PeiServices = GetPeiServicesTablePointer ();
+
+  Status = (**PeiServices).LocatePpi (PeiServices, &gEfiPeiStallPpiGuid, 0, NULL, (VOID **) &StallPpi);
+  ASSERT(!EFI_ERROR(Status));
+
+  StallPpi->Stall (PeiServices, StallPpi, MicroSeconds);
+
+  return EFI_SUCCESS;
+
+}
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.h
new file mode 100644
index 0000000..53ab6e0
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CDelayPei.h
@@ -0,0 +1,34 @@
+/** @file
+  imer prototype for I2C Pei Library.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _I2C_DELAY_PEI_
+#define _I2C_DELAY_PEI_
+
+#include <PiPei.h>
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  @param[in]  MicroSeconds     The minimum number of microseconds to delay.
+
+  @retval  EFI_SUCCESS         Time delay successfully
+**/
+EFI_STATUS
+EFIAPI
+MicroSecondDelay (
+  IN UINTN                     MicroSeconds
+  );
+
+#endif
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.c
new file mode 100644
index 0000000..f4cc843
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.c
@@ -0,0 +1,175 @@
+/** @file
+  IO instance for I2C Pei Library.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <PiPei.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+
+
+/**
+  Reads an 8-bit MMIO register.
+
+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 8-bit MMIO register operations are not supported, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT8        - The UINT8 value read.
+**/
+UINT8
+EFIAPI
+I2CLibPeiMmioRead8 (
+  IN      UINTN                     Address
+  )
+{
+  UINT8                             Value;
+
+  Value = *(volatile UINT8*)Address;
+  return Value;
+}
+
+/**
+  Reads a 16-bit MMIO register.
+
+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT16       - The UINT16 value read.
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioRead16 (
+  IN      UINTN                     Address
+  )
+{
+  UINT16                            Value;
+
+  ASSERT ((Address & 1) == 0);
+  Value = *(volatile UINT16*)Address;
+  return Value;
+}
+
+/**
+  Writes a 16-bit MMIO register.
+
+  Writes the 16-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  Value    - The value to write to the MMIO register.
+
+  @retval UINT16       - The UINT16 value written.
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioWrite16 (
+  IN      UINTN                     Address,
+  IN      UINT16                    Value
+  )
+{
+  ASSERT ((Address & 1) == 0);
+  *(volatile UINT16*)Address = Value;
+  return Value;
+}
+
+/**
+  Reads a 32-bit MMIO register.
+
+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT32       - The UINT32 value read.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioRead32 (
+  IN      UINTN                     Address
+  )
+{
+  UINT32                            Value;
+
+  ASSERT ((Address & 3) == 0);
+  Value = *(volatile UINT32*)Address;
+
+  return Value;
+}
+
+/**
+  Writes a 32-bit MMIO register.
+
+  Writes the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  Value    - The value to write to the MMIO register.
+
+  @retval UINT32       - The UINT32 value written.
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  )
+{
+  ASSERT ((Address & 3) == 0);
+  *(volatile UINT32*)Address = Value;
+  return Value;
+}
+
+/**
+  Do logical OR operation with the value read from the 32-bit  MMIO register
+  and write it back to 32-bit MMIO register.
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  OrData   - The value to do logical OR operation with the value read from the MMIO register.
+
+  @retval UINT32       - The final value written to the MMIO register.
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  )
+{
+  return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32 (Address) | OrData);
+}
+
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.h
new file mode 100644
index 0000000..0ea1727
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CIoLibPei.h
@@ -0,0 +1,146 @@
+/** @file
+  IO prototype for I2C Pei Library.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _I2C_IOLIB_PEI_
+#define _I2C_IOLIB_PEI_
+
+#include <PiPei.h>
+
+/**
+  Reads an 8-bit MMIO register.
+
+  Reads the 8-bit MMIO register specified by Address. The 8-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 8-bit MMIO register operations are not supported, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT8        - The UINT8 value read.
+**/
+UINT8
+EFIAPI
+I2CLibPeiMmioRead8 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Reads a 16-bit MMIO register.
+
+  Reads the 16-bit MMIO register specified by Address. The 16-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT16       - The UINT16 value read.
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioRead16 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Writes a 16-bit MMIO register.
+
+  Writes the 16-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 16-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 16-bit boundary, then ASSERT().
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  Value    - The value to write to the MMIO register.
+
+  @retval UINT16       - The UINT16 value written.
+**/
+UINT16
+EFIAPI
+I2CLibPeiMmioWrite16 (
+  IN      UINTN                     Address,
+  IN      UINT16                    Value
+  );
+
+
+/**
+  Reads a 32-bit MMIO register.
+
+  Reads the 32-bit MMIO register specified by Address. The 32-bit read value is
+  returned. This function must guarantee that all MMIO read and write
+  operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param[in] Address   - The MMIO register to read.
+
+  @retval UINT32       - The UINT32 value read.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioRead32 (
+  IN      UINTN                     Address
+  );
+
+
+/**
+  Writes a 32-bit MMIO register.
+
+  Writes the 32-bit MMIO register specified by Address with the value specified
+  by Value and returns Value. This function must guarantee that all MMIO read
+  and write operations are serialized.
+
+  If 32-bit MMIO register operations are not supported, then ASSERT().
+  If Address is not aligned on a 32-bit boundary, then ASSERT().
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  Value    - The value to write to the MMIO register.
+
+  @retval UINT32       - The UINT32 value written.
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  Do logical OR operation with the value read from the 32-bit  MMIO register
+  and write it back to 32-bit MMIO register.
+
+  @param[in]  Address  - The MMIO register to write.
+  @param[in]  OrData   - The value to do logical OR operation with the value read from the MMIO register.
+
+  @retval UINT32       - The final value written to the MMIO register.
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  );
+
+#endif
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
new file mode 100644
index 0000000..fd66671
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
@@ -0,0 +1,665 @@
+/** @file
+  Pei library for I2C bus driver.
+
+  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD License
+  which accompanies this distribution.  The full text of the license may be found at
+  http://opensource.org/licenses/bsd-license.php.
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "I2CDelayPei.h"
+#include "I2CIoLibPei.h"
+#include "I2CAccess.h"
+#include <Library/I2CLib.h>
+#include <PlatformBaseAddresses.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <ScRegs/RegsPcu.h>
+#include <ScRegs/RegsPmc.h>
+#include <ScRegs/RegsLpss.h>
+#include <ScRegs/RegsI2c.h>
+
+EFI_GUID  mI2CPeiInitGuid = {
+  0x96DED71A, 0xB9E7, 0x4EAD, 0x96, 0x2C, 0x01, 0x69, 0x3C, 0xED, 0x2A, 0x64
+};
+
+
+#define LPSS_PCI_DEVICE_NUMBER  8
+
+
+#define GPIO_PAD_CFG_DW0_GPIO_124_OFFSET  0x400  ///< This is the first gpio pin of I2C0
+
+/*  Name    Function       Offset of GPIO WEST
+  GPIO_124  LPSS_I2C0_SDA  0x400 + 16*0
+  GPIO_125  LPSS_I2C0_SCL
+
+  GPIO_126  LPSS_I2C1_SDA  0x400 + 16*1
+  GPIO_127  LPSS_I2C1_SCL
+
+  GPIO_128  LPSS_I2C2_SDA
+  GPIO_129  LPSS_I2C2_SCL
+
+  GPIO_130  LPSS_I2C3_SDA
+  GPIO_131  LPSS_I2C3_SCL
+
+  GPIO_132  LPSS_I2C4_SDA
+  GPIO_133  LPSS_I2C4_SCL
+
+  GPIO_134  LPSS_I2C5_SDA
+  GPIO_135  LPSS_I2C5_SCL
+
+  GPIO_136  LPSS_I2C6_SDA
+  GPIO_137  LPSS_I2C6_SCL
+
+  GPIO_138  LPSS_I2C7_SDA  0x400 + 16*7
+  GPIO_139  LPSS_I2C7_SCL
+*/
+
+EFI_STATUS
+EFIAPI
+IntelI2CPeiLibConstructor (
+  VOID
+  )
+{
+  UINTN     Index;
+//UINT32    Value;
+  UINT32    gpio_pad_cfg_dw0_offset;
+
+  // Program GPIO pins for I2C 0~7, need to set GPIO to Function 1 and misc settings.
+  for (Index = 0; Index < 8; Index ++) {
+   // Config I2C[Index] SDA pin DW0
+    gpio_pad_cfg_dw0_offset = GPIO_PAD_CFG_DW0_GPIO_124_OFFSET + 16 * Index;
+    {
+      //Value = 0;  // FIXME: the right GPIO setting, need to get updated from GPIO config owner. Dummy code here.
+      //SideBandCR32Write (SB_PORTID_GPIOW, gpio_pad_cfg_dw0_offset, Value);
+    }
+
+    // Config I2C[Index] SDA pin DW1
+    gpio_pad_cfg_dw0_offset += 4;
+    {
+      //Value = 0;  // FIXME: the right GPIO setting, need to get updated from GPIO config owner. Dummy code here.
+      //SideBandCR32Write (SB_PORTID_GPIOW, gpio_pad_cfg_dw0_offset, Value);
+    }
+
+    // Config I2C[Index] SCL pin DW0
+    gpio_pad_cfg_dw0_offset += 4;
+    {
+      //Value = 0;  // FIXME: the right GPIO setting, need to get updated from GPIO config owner. Dummy code here.
+      //SideBandCR32Write (SB_PORTID_GPIOW, gpio_pad_cfg_dw0_offset, Value);
+    }
+
+    // Config I2C[Index] SCL pin DW1
+    gpio_pad_cfg_dw0_offset += 4;
+    {
+      //Value = 0;  // FIXME: the right GPIO setting, need to get updated from GPIO config owner. Dummy code here.
+      //SideBandCR32Write (SB_PORTID_GPIOW, gpio_pad_cfg_dw0_offset, Value);
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Program LPSS I2C PCI controller's BAR0 and enable memory decode.
+
+  @retval EFI_SUCCESS           - I2C controller's BAR0 is programmed and memory decode enabled.
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  VOID
+  )
+{
+  UINT32       PmcBase;
+  UINT32       DevID;
+  UINTN        PciMmBase=0;
+  UINTN        Index;
+  UINTN        Bar0;
+  UINTN        Bar1;
+
+  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() Start\n"));
+
+  //
+  // Set the BXT Function Disable Register to ZERO
+  //
+  PmcBase = PMC_BASE_ADDRESS;
+
+  if (I2CLibPeiMmioRead32 (PmcBase + R_PMC_FUNC_DIS) &
+      (B_PMC_FUNC_DIS_LPSS_I2C0 | B_PMC_FUNC_DIS_LPSS_I2C1 | B_PMC_FUNC_DIS_LPSS_I2C2 | B_PMC_FUNC_DIS_LPSS_I2C3|
+       B_PMC_FUNC_DIS_LPSS_I2C4 | B_PMC_FUNC_DIS_LPSS_I2C5 | B_PMC_FUNC_DIS_LPSS_I2C6 | B_PMC_FUNC_DIS_LPSS_I2C7)) {
+    I2CLibPeiMmioWrite32 (
+      PmcBase + R_PMC_FUNC_DIS,
+      I2CLibPeiMmioRead32 (PmcBase + R_PMC_FUNC_DIS) &
+            ~(B_PMC_FUNC_DIS_LPSS_I2C0| B_PMC_FUNC_DIS_LPSS_I2C1|B_PMC_FUNC_DIS_LPSS_I2C2| B_PMC_FUNC_DIS_LPSS_I2C3|
+              B_PMC_FUNC_DIS_LPSS_I2C4| B_PMC_FUNC_DIS_LPSS_I2C5|B_PMC_FUNC_DIS_LPSS_I2C6| B_PMC_FUNC_DIS_LPSS_I2C7)
+      );
+
+    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
+  }
+
+  for (Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {
+    if (Index < 4) {
+      PciMmBase = MmPciAddress (
+                    0,
+                    DEFAULT_PCI_BUS_NUMBER_SC,
+                    PCI_DEVICE_NUMBER_LPSS_I2C0,
+                    Index,
+                    0
+                    );
+    } else {
+      PciMmBase = MmPciAddress (
+                    0,
+                    DEFAULT_PCI_BUS_NUMBER_SC,
+                    PCI_DEVICE_NUMBER_LPSS_I2C1,
+                    (Index - 4),
+                    0
+                    );
+    }
+
+    DevID = I2CLibPeiMmioRead32 (PciMmBase);
+    Bar0  = LPSS_I2C0_TMP_BAR0 + Index * LPSS_I2C_TMP_BAR0_DELTA;
+    Bar1  = Bar0 + LPSS_I2C_TMP_BAR1_OFFSET;
+
+    //
+    // Check if device present
+    //
+    if (DevID != 0xFFFFFFFF) {
+      if ((I2CLibPeiMmioRead32 (PciMmBase + R_LPSS_I2C_STSCMD) & B_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // In PEI stage, we always disable Bus master, and memory space enabling for BAR re-programming
+        // In DXE stage, will read existing BAR value instead of re-programming
+        //
+        I2CLibPeiMmioWrite32 ((UINTN) (PciMmBase + R_LPSS_I2C_STSCMD), 0);
+      }
+      //
+      // Program BAR 0
+      //
+      I2CLibPeiMmioWrite32 ((UINTN) (PciMmBase + R_LPSS_I2C_BAR), (UINT32) (Bar0 & B_LPSS_I2C_BAR_BA));
+
+      //
+      // Program BAR 1
+      //
+      I2CLibPeiMmioWrite32 ((UINTN) (PciMmBase + R_LPSS_I2C_BAR1), (UINT32) (Bar1 & B_LPSS_I2C_BAR1_BA));
+
+      //
+      // Bus Master Enable & Memory Space Enable
+      //
+      I2CLibPeiMmioWrite32 ((UINTN) (PciMmBase + R_LPSS_I2C_STSCMD), (UINT32) (B_LPSS_I2C_STSCMD_BME | B_LPSS_I2C_STSCMD_MSE));
+    }
+
+    //
+    // Release Resets
+    //
+    I2CLibPeiMmioWrite32 (Bar0 + R_LPSS_IO_MEM_RESETS, B_LPSS_IO_MEM_HC_RESET_REL | B_LPSS_IO_MEM_iDMA_RESET_REL);
+  }
+
+  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable I2C host controller
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+
+  @retval EFI_SUCCESS           - I2C host controller is completely inactive.
+  @retval EFI_NOT_READY         - I2C host controller is still in an enabled state.
+**/
+EFI_STATUS
+I2cDisable (
+  IN UINT8 BusNo
+  )
+{
+  UINTN    I2CBaseAddress;
+  UINT32   NumTries = 10000;  // 0.1 seconds
+
+  I2CBaseAddress = (UINT32) LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 0);
+  while (0 != (I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_ENABLE) & 1)) {
+    MicroSecondDelay (10);
+    NumTries--;
+    if (NumTries == 0) return EFI_NOT_READY;
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Enable I2C host controller
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+
+  @retval EFI_SUCCESS           - I2C host controller is in an enabled state.
+  @retval EFI_NOT_READY         - I2C host controller is still inactive.
+**/
+EFI_STATUS
+I2cEnable (
+  IN UINT8    BusNo
+  )
+{
+  UINTN    I2CBaseAddress;
+  UINT32   NumTries = 10000;  //0.1 seconds
+
+  I2CBaseAddress = (UINT32) LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 1);
+  while (0 == (I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_ENABLE ) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if (NumTries == 0) return EFI_NOT_READY;
+  }
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Set the I2C controller bus clock frequency.
+
+  The software and controller do a best case effort of using the specified
+  frequency for the I2C bus.  If the frequency does not match exactly then
+  the controller will use a slightly lower frequency for the I2C to avoid
+  exceeding the operating conditions for any of the I2C devices on the bus.
+  For example if 400 KHz was specified and the controller's divide network
+  only supports 402 KHz or 398 KHz then the controller would be set to 398
+  KHz.  However if the desired frequency is 400 KHz and the controller only
+  supports 1 MHz and 100 KHz then this routine would return EFI_UNSUPPORTED.
+
+  @param[in]  I2CBaseAddress    - BAR0 address of I2C host controller
+  @param[in]  BusClockHertz     - New I2C bus clock frequency in Hertz
+  @param[out] I2cMode           - I2C operation mode.
+                                  Standard Speed: 100 KHz
+                                  Fast Speed    : 400 KHz
+                                  High Speed    : 3.4 MHz
+
+  @retval EFI_SUCCESS           - The bus frequency was set successfully.
+**/
+
+EFI_STATUS
+I2cBusFrequencySet (
+  IN  UINTN     I2CBaseAddress,
+  IN  UINTN     BusClockHertz,
+  OUT UINT16    *I2cMode,
+  IN  BOOLEAN   DebugFlag
+  )
+{
+  if (DebugFlag) DEBUG ((EFI_D_INFO, "InputFreq BusClockHertz: %d\r\n", BusClockHertz));
+
+  *I2cMode = B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+
+  //
+  //  Set the 100 KHz clock divider
+  //  From Table 10 of the I2C specification
+  //    High: 4.00 uS
+  //    Low:  4.70 uS
+  //
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272);
+
+  //
+  // Set the 400 KHz clock divider
+  // From Table 10 of the I2C specification
+  //   High: 0.60 uS
+  //   Low:  1.30 uS
+  //
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD);
+
+  switch (BusClockHertz) {
+    case 100 * 1000:
+      I2CLibPeiMmioWrite32 (I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
+      *I2cMode |= V_SPEED_STANDARD;
+      break;
+    case 400 * 1000:
+      I2CLibPeiMmioWrite32 (I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
+      *I2cMode |= V_SPEED_FAST;
+      break;
+    default:
+      I2CLibPeiMmioWrite32 (I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
+      *I2cMode |= V_SPEED_HIGH;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initializes the host controller to execute I2C commands.
+
+  @param[in]  BusNo               - I2C Bus number to which the I2C device has been connected
+  @param[in]  SlaveAddress        - Slave address of the I2C device
+
+  @retval  EFI_SUCCESS            - Opcode initialization on the I2C host controller completed.
+  @retval  EFI_INVALID_PARAMETER  - Invalid slave address
+  @retval  EFI_DEVICE_ERROR       - Operation failed, device error
+  @retval  Others                 - Failed to initialize I2C host controller
+**/
+EFI_STATUS
+I2CInit (
+  IN UINT8     BusNo,
+  IN UINT16    SlaveAddress
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        NumTries = 0;
+  UINTN         I2CBaseAddress;
+  UINT16        I2cMode;
+  UINTN         PciMmBase = 0;
+  BOOLEAN       DebugFlag = TRUE;
+
+  if (BusNo < 4) {
+    PciMmBase = MmPciAddress (
+                  0,
+                  DEFAULT_PCI_BUS_NUMBER_SC,
+                  PCI_DEVICE_NUMBER_LPSS_I2C0,
+                  BusNo,
+                  0
+                  );
+  } else {
+    PciMmBase = MmPciAddress (
+                  0,
+                  DEFAULT_PCI_BUS_NUMBER_SC,
+                  PCI_DEVICE_NUMBER_LPSS_I2C1,
+                  (BusNo - 4),
+                  0
+                  );
+  }
+
+  I2CBaseAddress = (I2CLibPeiMmioRead32 (PciMmBase + R_LPSS_I2C_BAR) & 0xFFFFFFF8);
+
+  //
+  //  Verify the parameters
+  //
+  if (1023 < SlaveAddress) {
+    Status =  EFI_INVALID_PARAMETER;
+    if (DebugFlag) DEBUG ((DEBUG_ERROR, "I2cStartRequest Exit with Status %r\r\n", Status));
+    return Status;
+  }
+
+  if (I2CBaseAddress == (LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA))) {
+    DebugFlag = FALSE;
+  } else {
+    //
+    // Need to enable the I2C PCI device
+    //
+    ProgramPciLpssI2C ();
+
+    I2CBaseAddress = (UINT32) (LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA));
+    if (DebugFlag) DEBUG ((DEBUG_INFO, "I2CBaseAddress = 0x%x \n", I2CBaseAddress));
+  }
+
+  NumTries = 10000; // 1 seconds 
+  while ((1 == (I2CLibPeiMmioRead32 (I2CBaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY ))) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if (0 == NumTries)
+      return EFI_DEVICE_ERROR;
+  }
+
+  Status = I2cDisable (BusNo);
+  if (DebugFlag) DEBUG ((DEBUG_INFO, "I2cDisable Status = %r\r\n", Status));
+
+  I2cBusFrequencySet (I2CBaseAddress, 400 * 1000, &I2cMode, DebugFlag); // Set I2cMode
+
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_INTR_MASK, 0x0);
+  if (0x7F < SlaveAddress) {
+    SlaveAddress = (SlaveAddress & 0x3FF) | IC_TAR_10BITADDR_MASTER;
+  }
+
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TAR,   (UINT16) SlaveAddress);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_RX_TL, 0);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_TX_TL, 0);
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_CON,   I2cMode);
+
+  Status = I2cEnable (BusNo);
+  if (DebugFlag) DEBUG ((DEBUG_INFO, "I2cEnable Status = %r\r\n", Status));
+
+  I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+  return EFI_SUCCESS;
+}
+
+/**
+  Read bytes from I2C Device
+  This is actual I2C hardware operation function.
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+  @param[in]  SlaveAddress      - Slave address of the I2C device (7-bit)
+  @param[in]  ReadBytes         - Number of bytes to be read
+  @param[out] ReadBuffer        - Address to which the value read has to be stored
+  @param[in]  Start             - It controls whether a RESTART is issued before the byte is sent or received.
+  @param[in]  End               - It controls whether a STOP is issued after the byte is sent or received.
+
+  @retval EFI_SUCCESS           - The byte value read successfully
+  @retval EFI_DEVICE_ERROR      - Operation failed
+  @retval EFI_TIMEOUT           - Hardware retry timeout
+  @retval Others                - Failed to read a byte via I2C
+**/
+EFI_STATUS
+ByteReadI2C_Basic (
+  IN  UINT8        BusNo,
+  IN  UINT8        SlaveAddress,
+  IN  UINTN        ReadBytes,
+  OUT UINT8        *ReadBuffer,
+  IN  UINT8        Start,
+  IN  UINT8        End
+  )
+{
+  EFI_STATUS    Status;
+  UINT32        I2cStatus;
+  UINT16        ReceiveData;
+  UINT8         *ReceiveDataEnd;
+  UINT8         *ReceiveRequest;
+  UINT16        raw_intr_stat;
+  UINTN         I2CBaseAddress;
+
+  I2CBaseAddress = (UINT32) (LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA));
+
+  Status = EFI_SUCCESS;
+
+  I2CInit (BusNo, SlaveAddress);
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  if (ReadBytes) {
+    ReceiveRequest = ReadBuffer;
+
+    while ((ReceiveDataEnd > ReceiveRequest) ||
+           (ReceiveDataEnd > ReadBuffer)) {
+      //
+      // Check for NACK
+      //
+      raw_intr_stat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+      if (0 != (raw_intr_stat & I2C_INTR_TX_ABRT)) {
+        I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG ((DEBUG_INFO,"TX ABRT ,%d bytes hasn't been transferred\r\n", ReceiveDataEnd - ReceiveRequest));
+        break;
+      }
+
+      //
+      // Determine if another byte was received
+      //
+      I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
+      if (0 != (I2cStatus & STAT_RFNE)) {
+        ReceiveData = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_DATA_CMD);
+        *ReadBuffer++ = (UINT8)ReceiveData;
+      }
+
+      if (ReceiveDataEnd == ReceiveRequest) {
+        continue; //Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+      }
+
+      //
+      // Wait until a read request will fit
+      //
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        MicroSecondDelay (10);
+        continue;
+      }
+
+      //
+      // Issue the next read request
+      //
+      if (End && Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD | B_CMD_RESTART | B_CMD_STOP);
+      } else if (!End && Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD | B_CMD_RESTART);
+      } else if (End && !Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD | B_CMD_STOP);
+      } else if (!End && !Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
+      }
+      ReceiveRequest += 1;
+    }
+  }
+  return Status;
+
+}
+
+/**
+  Write bytes to I2C Device
+  This is actual I2C hardware operation function.
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+  @param[in]  SlaveAddress      - Slave address of the I2C device (7-bit)
+  @param[in]  WriteBytes        - Number of bytes to be written
+  @param[in]  WriteBuffer       - Address to which the byte value has to be written
+  @param[in]  Start             - It controls whether a RESTART is issued before the byte is sent or received.
+  @param[in]  End               - It controls whether a STOP is issued after the byte is sent or received.
+
+  @retval EFI_SUCCESS           - The byte value written successfully
+  @retval EFI_DEVICE_ERROR      - Operation failed
+  @retval EFI_TIMEOUT           - Hardware retry timeout
+  @retval Others                - Failed to write a byte via I2C
+**/
+EFI_STATUS
+ByteWriteI2C_Basic (
+  IN  UINT8        BusNo,
+  IN  UINT8        SlaveAddress,
+  IN  UINTN        WriteBytes,
+  IN  UINT8        *WriteBuffer,
+  IN  UINT8        Start,
+  IN  UINT8        End
+  )
+{
+  UINT16        Data16;
+  EFI_STATUS    Status;
+  UINT32        I2cStatus;
+  UINT8         *TransmitPtr;
+  UINT8         *TransmitEnd;
+  UINT16        raw_intr_stat;
+  UINTN         I2CBaseAddress;
+
+
+  I2CBaseAddress = (UINT32)LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA);
+  Status = EFI_SUCCESS;
+  I2CInit (BusNo, SlaveAddress);
+
+  TransmitPtr = WriteBuffer;
+  TransmitEnd = &WriteBuffer[WriteBytes];
+  if (WriteBytes > 0x00) {
+
+
+    while (TransmitEnd > TransmitPtr) {
+      I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
+      raw_intr_stat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+      if (0 != (raw_intr_stat & I2C_INTR_TX_ABRT)) {
+        I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG ((DEBUG_ERROR,"TX ABRT TransmitEnd:0x%x WritePtr:0x%x\r\n", TransmitEnd, TransmitPtr));
+        break;
+      }
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        DEBUG ((DEBUG_INFO,"%a(#%d) - 0 == (I2cStatus & STAT_TFNF)\n", __FUNCTION__, __LINE__));
+        continue;
+      }
+
+      Data16 = (UINT16) *TransmitPtr;
+      if (End && Start) {
+        Data16 |= (B_CMD_RESTART | B_CMD_STOP);
+      } else if (!End && Start) {
+        Data16 |= B_CMD_RESTART;
+      } else if (End && !Start) {
+        Data16 |= B_CMD_STOP;
+      }
+      Data16 = I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, Data16);
+      TransmitPtr++;
+
+      //
+      // Add a small delay to work around some odd behavior being seen.  Without this delay bytes get dropped.
+      //
+      MicroSecondDelay (FIFO_WRITE_DELAY);
+    }
+
+  }
+
+  if (EFI_ERROR (Status))
+    DEBUG ((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
+
+  return Status;
+}
+
+
+/**
+  Read bytes from I2C Device
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+  @param[in]  SlaveAddress      - Slave address of the I2C device (7-bit)
+  @param[in]  Offset            - Register offset from which the data has to be read
+  @param[in]  ReadBytes         - Number of bytes to be read
+  @param[out] ReadBuffer        - Address to which the value read has to be stored
+
+  @retval EFI_SUCCESS           - Read bytes from I2C device successfully
+  @retval Others                - Return status depends on ByteReadI2C_Basic
+**/
+EFI_STATUS
+ByteReadI2C (
+  IN  UINT8        BusNo,
+  IN  UINT8        SlaveAddress,
+  IN  UINT8        Offset,
+  IN  UINTN        ReadBytes,
+  OUT UINT8        *ReadBuffer
+  )
+{
+  EFI_STATUS    Status;
+
+  Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FALSE);
+  if (EFI_ERROR (Status)) return Status;
+  Status = ByteReadI2C_Basic (BusNo, SlaveAddress, ReadBytes, ReadBuffer, TRUE, TRUE);
+
+  return Status;
+}
+
+/**
+  Write bytes to I2C Device
+
+  @param[in]  BusNo             - I2C Bus number to which the I2C device has been connected
+  @param[in]  SlaveAddress      - Slave address of the I2C device (7-bit)
+  @param[in]  Offset            - Register offset from which the data has to be read
+  @param[in]  WriteBytes        - Number of bytes to be written
+  @param[in]  WriteBuffer       - Address to which the byte value has to be written
+
+  @retval EFI_SUCCESS           - Write bytes to I2C device successfully
+  @retval Others                - Return status depends on ByteWriteI2C_Basic
+**/
+EFI_STATUS
+ByteWriteI2C (
+  IN  UINT8        BusNo,
+  IN  UINT8        SlaveAddress,
+  IN  UINT8        Offset,
+  IN  UINTN        WriteBytes,
+  IN  UINT8        *WriteBuffer
+  )
+{
+  EFI_STATUS        Status;
+
+  Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FALSE);
+  if (EFI_ERROR (Status)) return Status;
+  Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, WriteBytes, WriteBuffer, FALSE, TRUE);
+
+  return Status;
+}
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.inf
new file mode 100644
index 0000000..1f920bb
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.inf
@@ -0,0 +1,51 @@
+## @file
+#  Pei library for I2C bus driver.
+#
+#  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<BR>
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution. The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php.
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = I2CLibPei
+  FILE_GUID                      = 8EF61509-890B-4FF2-B352-1C0E9CDDEC8B
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2CLibPei
+
+  CONSTRUCTOR                    = IntelI2CPeiLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+  I2CLibPei.c
+  I2CDelayPei.c
+  I2CIoLibPei.c
+
+[LibraryClasses]
+
+[PPIs]
+  gEfiPeiStallPpiGuid ## CONSUMES
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES
+  gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress        ## CONSUMES
+
+
+
-- 
2.10.1.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel