public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: zwei4 <david.wei@intel.com>
To: edk2-devel@lists.01.org
Cc: David Wei <david.wei@intel.com>,
	Kelly Steele <kelly.steele@intel.com>,
	Mike Wu <mike.wu@intel.com>, Mang Guo <mang.guo@intel.com>
Subject: [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Add I2C Library.
Date: Thu, 26 Jul 2018 11:54:40 +0800	[thread overview]
Message-ID: <20180726035440.15832-1-david.wei@intel.com> (raw)

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: David Wei <david.wei@intel.com>
CC: Kelly Steele <kelly.steele@intel.com>
CC: Mike Wu  <mike.wu@intel.com>
CC: Mang Guo <mang.guo@intel.com>
---
 .../SouthCluster/Include/Library/I2CLib.h          |   4 +-
 .../SouthCluster/Include/ScRegs/RegsI2c.h          |  31 +-
 .../SouthCluster/Library/I2CLib/I2CLib.c           | 719 +++++++++++++++++++++
 .../SouthCluster/Library/I2CLib/I2CLib.inf         |  50 ++
 .../SouthCluster/Library/I2CLibPei/I2CLibPei.c     |   6 +-
 5 files changed, 802 insertions(+), 8 deletions(-)
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.c
 create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.inf

diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h
index b897cb9dc4..0c50a3d9a5 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 - 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 1999 - 2018, 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
@@ -30,7 +30,7 @@
 **/
 EFI_STATUS
 ProgramPciLpssI2C (
-  VOID
+  IN UINT8        BusNo
   );
 
 /**
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
index 5fc758dd07..8a7463b538 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h
@@ -106,10 +106,10 @@
 #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    I2C_ENABLE_ABORT                  BIT1
+#define    I2C_ENABLE_ENABLE                 BIT0
 #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
@@ -118,7 +118,24 @@
 
 #define    R_IC_TXFLR                        (0x74) ///< Transmit FIFO Level Register
 #define    R_IC_RXFLR                        (0x78) ///< Receive FIFO Level Register
+#define    R_IC_SDA_HOLD                     (0x7C) ///< I2C IC_DEFAULT_SDA_HOLD//16bits
 #define    R_IC_TX_ABRT_SOURCE               (0x80) ///< I2C Transmit Abort Status Register
+#define    I2C_ABRT_SLVRD_INTX               BIT15
+#define    I2C_ABRT_SLV_ARBLOST              BIT14
+#define    I2C_ABRT_SLVFLUSH_TXFIFO          BIT13
+#define    I2C_ARB_LOST                      BIT12
+#define    I2C_ABRT_MASTER_DIS               BIT11
+#define    I2C_ABRT_10B_RD_NORSTRT           BIT10
+#define    I2C_ABRT_SBYTE_NORSTRT            BIT9
+#define    I2C_ABRT_HS_NORSTRT               BIT8
+#define    I2C_ABRT_SBYTE_ACKDET             BIT7
+#define    I2C_ABRT_HS_ACKDET                BIT6
+#define    I2C_ABRT_GCALL_READ               BIT5
+#define    I2C_ABRT_GCALL_NOACK              BIT4
+#define    I2C_ABRT_TXDATA_NOACK             BIT3
+#define    I2C_ABRT_10ADDR2_NOACK            BIT2
+#define    I2C_ABRT_10ADDR1_NOACK            BIT1
+#define    I2C_ABRT_7B_ADDR_NOACK            BIT0
 #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
@@ -130,7 +147,15 @@
 #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    R_IC_RESET_CONTROL                (0x204) ///< Reset control
+#define    I2C_RESET_CONTROLLER              (BIT0 | BIT1)
+#define    I2C_RESET_IDMA                    (BIT2)
+
+#define    R_IC_CLK_GATE                     (0x238) ///< Clock Gate
+#define    I2C_FORCE_CLOCK_ON                (BIT0 | BIT1)
+#define    I2C_FORCE_CLOCK_OFF               (BIT1)
+#define    I2C_FORCE_IDMA_CLOCK_ON           (BIT2 | BIT3)
+#define    I2C_FORCE_IDMA_CLOCK_OFF          (BIT3)
 
 #define    I2C_SS_SCL_HCNT_VALUE_100M         0x1DD
 #define    I2C_SS_SCL_LCNT_VALUE_100M         0x1E4
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.c
new file mode 100644
index 0000000000..f205a6ce44
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.c
@@ -0,0 +1,719 @@
+/** @file
+  Dxe library for I2C bus driver.
+
+@copyright
+ Copyright (c) 1999 - 2018 Intel Corporation. All rights reserved
+
+  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 <Library/DebugLib.h>
+#include <Library/I2CLib.h>
+#include <Library/TimerLib.h>
+#include <PlatformBaseAddresses.h>
+#include <SaAccess.h>
+#include <ScAccess.h>
+#include <ScRegs/RegsI2c.h>
+
+#pragma pack(push, 1)
+typedef struct _LPSS_PCI_DEVICE_INFO {
+  UINTN        Segment;
+  UINTN        BusNum;
+  UINTN        DeviceNum;
+  UINTN        FunctionNum;
+  UINTN        Bar0;
+  UINTN        Bar1;
+} LPSS_PCI_DEVICE_INFO;
+
+typedef enum {
+  Standard_Speed = 1,
+  Fast_Speed = 2,
+  High_Speed = 3,
+} I2C_SPEED;
+
+typedef struct _LPSS_I2C_CLOCK_SCL_INFO {
+  UINT8        I2c_Speed;
+  UINT16       SS_SCL_HCNT;
+  UINT16       SS_SCL_LCNT;
+  UINT16       FS_SCL_HCNT;
+  UINT16       FS_SCL_LCNT;
+  UINT16       HS_SCL_HCNT;
+  UINT16       HS_SCL_LCNT;
+} LPSS_I2C_CLOCK_SCL_INFO;
+#pragma pack(pop)
+
+LPSS_PCI_DEVICE_INFO  mLpssPciDeviceList[] = {
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0,   PCI_FUNCTION_NUMBER_LPSS_I2C0, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0,   PCI_FUNCTION_NUMBER_LPSS_I2C1, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0,   PCI_FUNCTION_NUMBER_LPSS_I2C2, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0,   PCI_FUNCTION_NUMBER_LPSS_I2C3, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1,   PCI_FUNCTION_NUMBER_LPSS_I2C4, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1,   PCI_FUNCTION_NUMBER_LPSS_I2C5, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1,   PCI_FUNCTION_NUMBER_LPSS_I2C6, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6) + LPSS_I2C_TMP_BAR1_OFFSET},
+  {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1,   PCI_FUNCTION_NUMBER_LPSS_I2C7, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7), LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7) + LPSS_I2C_TMP_BAR1_OFFSET},
+};
+
+#define LPSS_PCI_DEVICE_NUMBER  sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
+
+LPSS_I2C_CLOCK_SCL_INFO  mLPSS_I2C_CLOCK_SCL_INFO[] = {
+  {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+  {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+  {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13},
+  {High_Speed, 0x244, 0x2DA, 0x1E, 0x3C, 0x06, 0x13},
+  {High_Speed, 0x244, 0x2DA, 0x1E, 0x50, 0x06, 0x13},
+  {Fast_Speed, 0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13},
+  {Fast_Speed, 0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13},
+  {Fast_Speed, 0x244, 0x2D0, 0x70, 0xC8, 0x06, 0x13},
+};
+
+#define LPSS_I2C_CLOCK_SCL_INFO_NUMBER  sizeof(mLPSS_I2C_CLOCK_SCL_INFO)/sizeof(LPSS_I2C_CLOCK_SCL_INFO)
+
+
+/**
+  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.
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  IN UINT8        BusNo
+  )
+{
+  UINTN  PciMmBase=0;
+  UINT32 I2CBar0;
+  UINT32 I2CBar1;
+  UINT32 PmcBase;
+  UINT32 D32;
+  UINT32 I2cPortDisable[] = {
+    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 ((DEBUG_INFO, "ProgramPciLpssI2C() Start\n"));
+
+  //
+  // Check PMC disable register
+  //
+  PmcBase = PMC_BASE_ADDRESS;
+  D32     = MmioRead32 (PmcBase + R_PMC_FUNC_DIS);
+
+  if (D32 == 0xFFFFFFFF) {
+    DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() PMC disable register not available. [%08x]\n", PMC_BASE_ADDRESS));
+  } else {
+    if ((D32 & I2cPortDisable[BusNo]) != 0) {
+      // This I2C port is disabled. Turn it on.
+      D32 &= ~I2cPortDisable[BusNo];
+      MmioWrite32 (PmcBase + R_PMC_FUNC_DIS, D32);
+      DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() enable I2C controller #%x\n", BusNo));
+      // Make sure it took.
+      if (D32 != MmioRead32 (PmcBase + R_PMC_FUNC_DIS)) {
+        DEBUG ((DEBUG_ERROR, "ProgramPciLpssI2C() failed to enable I2C controller #%x [%08x:%08x]\n", BusNo, D32, MmioRead32 (PmcBase + R_PMC_FUNC_DIS)));
+        return EFI_DEVICE_ERROR;
+      }
+    }
+  }
+
+  DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C()------------BusNo=%x\n", BusNo));
+
+  PciMmBase = MmPciAddress (
+                mLpssPciDeviceList[BusNo].Segment,
+                mLpssPciDeviceList[BusNo].BusNum,
+                mLpssPciDeviceList[BusNo].DeviceNum,
+                mLpssPciDeviceList[BusNo].FunctionNum,
+                0
+                );
+  DEBUG ((DEBUG_INFO, "Program Pci Lpss I2C Device  %x %x %x PciMmBase:%x\n", \
+      mLpssPciDeviceList[BusNo].BusNum, \
+      mLpssPciDeviceList[BusNo].DeviceNum, \
+      mLpssPciDeviceList[BusNo].FunctionNum, PciMmBase));
+
+  //
+  // Check if device present
+  //
+  if (MmioRead32 (PciMmBase) != 0xFFFFFFFF) {
+    if ((MmioRead32 (PciMmBase + R_LPSS_IO_STSCMD) & B_LPSS_IO_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
+      //
+      I2CBar0 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA;
+      I2CBar1 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR1) & B_LPSS_IO_BAR_BA;
+      if ((I2CBar0 != (UINT32)mLpssPciDeviceList[BusNo].Bar0) || (I2CBar1 != (UINT32)mLpssPciDeviceList[BusNo].Bar1)) {
+        mLpssPciDeviceList[BusNo].Bar0 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA;     // get the address allocated.
+        mLpssPciDeviceList[BusNo].Bar1 = MmioRead32 (PciMmBase + R_LPSS_IO_BAR1) & B_LPSS_IO_BAR_BA;
+        DEBUG ((DEBUG_INFO, "Get bar0:0x%x bar1:0x%x\n", mLpssPciDeviceList[BusNo].Bar0, mLpssPciDeviceList[BusNo].Bar1));
+      }
+    } else {
+      //
+      // Program BAR 0
+      //
+      ASSERT (((mLpssPciDeviceList[BusNo].Bar0 & B_LPSS_IO_BAR_BA) == mLpssPciDeviceList[BusNo].Bar0) && (mLpssPciDeviceList[BusNo].Bar0 != 0));
+      MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR), (UINT32) (mLpssPciDeviceList[BusNo].Bar0 & B_LPSS_IO_BAR_BA));
+      //
+      // Program BAR 1
+      //
+      ASSERT (((mLpssPciDeviceList[BusNo].Bar1 & B_LPSS_IO_BAR1_BA) == mLpssPciDeviceList[BusNo].Bar1) && (mLpssPciDeviceList[BusNo].Bar1 != 0));
+      MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR1), (UINT32) (mLpssPciDeviceList[BusNo].Bar1 & B_LPSS_IO_BAR1_BA));
+      //
+      // Bus Master Enable & Memory Space Enable
+      //
+      MmioOr32 ((UINTN) (PciMmBase + R_LPSS_IO_STSCMD), (UINT32) (B_LPSS_IO_STSCMD_BME | B_LPSS_IO_STSCMD_MSE));
+      ASSERT (MmioRead32 (mLpssPciDeviceList[BusNo].Bar0) != 0xFFFFFFFF);
+    }
+
+    //
+    // Release Resets
+    //
+    MmioWrite32 (mLpssPciDeviceList[BusNo].Bar0 + R_LPSS_IO_MEM_RESETS, B_LPSS_IO_MEM_HC_RESET_REL | B_LPSS_IO_MEM_iDMA_RESET_REL);
+
+    DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() Programmed()\n"));
+    return EFI_SUCCESS;
+  } else {
+     DEBUG ((DEBUG_ERROR, "Pci Lpss I2C Device  %x %x %x is not existing!\n",
+       mLpssPciDeviceList[BusNo].BusNum,
+       mLpssPciDeviceList[BusNo].DeviceNum,
+       mLpssPciDeviceList[BusNo].FunctionNum));
+
+     return EFI_NOT_READY;
+  }
+}
+
+/**
+  Disable I2C host controller
+
+  @param[in]  I2CBaseAddress    - BAR0 address of I2C host controller
+
+  @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 UINTN        I2CBaseAddress
+  )
+{
+  UINT32 NumTries = 10000;  // 0.1 seconds
+
+  MmioWrite32 (I2CBaseAddress + R_IC_ENABLE, 0);
+  while (0 != ( MmioRead32 ( I2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if (0 == NumTries) return EFI_NOT_READY;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
+  Enable I2C host controller
+
+  @param[in]  I2CBaseAddress    - BAR0 address of I2C host controller
+
+  @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 UINTN        I2CBaseAddress
+  )
+{
+  UINT32 NumTries = 10000;  // 0.1 seconds
+
+  MmioWrite32 (I2CBaseAddress + R_IC_ENABLE, 1);
+  while (0 == (MmioRead32 (I2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if (0 == NumTries) 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]  BusNo             - I2C Bus number to which the I2C device has been connected
+  @param[in]  I2CBaseAddress    - BAR0 address of I2C host controller
+  @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  UINT8   BusNo,
+  IN  UINTN   I2CBaseAddress,
+  OUT UINT16  *I2cMode
+  )
+{
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet bus: %d\r\n", BusNo));
+  ASSERT ((BusNo < LPSS_I2C_CLOCK_SCL_INFO_NUMBER));
+  //
+  //  Set the 100 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 (I2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].SS_SCL_HCNT);
+  MmioWrite32 (I2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].SS_SCL_LCNT);
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_SS_SCL_HCNT: 0x%08X, R_IC_SS_SCL_LCNT: 0x%08X\r\n",\
+         MmioRead32 (I2CBaseAddress + R_IC_SS_SCL_HCNT), MmioRead32 (I2CBaseAddress + R_IC_SS_SCL_LCNT)));
+  //
+  //  Set the 400 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 (I2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].FS_SCL_HCNT);
+  MmioWrite32 (I2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].FS_SCL_LCNT);
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_FS_SCL_HCNT: 0x%08X, R_IC_FS_SCL_LCNT: 0x%08X\r\n",\
+         MmioRead32 (I2CBaseAddress + R_IC_FS_SCL_HCNT), MmioRead32 (I2CBaseAddress + R_IC_FS_SCL_LCNT)));
+  //
+  //  Set the 3.4MHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 (I2CBaseAddress + R_IC_HS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].HS_SCL_HCNT);
+  MmioWrite32 (I2CBaseAddress + R_IC_HS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_SCL_INFO[BusNo].HS_SCL_LCNT);
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_HS_SCL_HCNT: 0x%08X, R_IC_HS_SCL_LCNT: 0x%08X\r\n",\
+         MmioRead32 (I2CBaseAddress + R_IC_HS_SCL_HCNT), MmioRead32 (I2CBaseAddress + R_IC_HS_SCL_LCNT)));
+
+  switch (mLPSS_I2C_CLOCK_SCL_INFO[BusNo].I2c_Speed) {
+    case Standard_Speed:
+      MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //100K
+      *I2cMode = V_SPEED_STANDARD;
+      DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode));
+      break;
+
+    case Fast_Speed:
+      MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //400K
+      *I2cMode = V_SPEED_FAST;
+      DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode));
+      break;
+
+    case High_Speed:
+      MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //3.4M
+      *I2cMode = V_SPEED_HIGH;
+      DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode));
+      break;
+
+    default:
+      MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //400K
+      *I2cMode = V_SPEED_FAST;
+      DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode));
+  }
+
+  //
+  //  Select the frequency counter
+  //  Enable restart condition,
+  //  Enable master FSM, disable slave FSM
+  //
+  *I2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_SDA_HOLD: 0x%08X\r\n", MmioRead32 (I2CBaseAddress + R_IC_SDA_HOLD)));
+  DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode));
+
+  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
+  @param[out] I2CBaseAddress      - Return BAR0 address of I2C host controller
+
+  @retval  EFI_SUCCESS            - 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,
+  OUT UINTN    *I2CBaseAddress
+  )
+{
+  EFI_STATUS Status;
+  UINT32     NumTries;
+  UINT16     I2cMode;
+  UINTN      PciMmBase;
+  UINTN      BaseAddress;
+
+  //
+  //  Verify the parameters
+  //
+  if (1023 < SlaveAddress) {
+    Status = EFI_INVALID_PARAMETER;
+    DEBUG ((DEBUG_INFO, "I2cStartRequest Exit with Status %r\r\n", Status));
+    return Status;
+  }
+
+  PciMmBase = MmPciAddress (
+                mLpssPciDeviceList[BusNo].Segment,
+                mLpssPciDeviceList[BusNo].BusNum,
+                mLpssPciDeviceList[BusNo].DeviceNum,
+                mLpssPciDeviceList[BusNo].FunctionNum,
+                0
+                );
+
+  BaseAddress = MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_BA;
+
+  //
+  // Skip reinit if targeting the same I2C bus
+  //
+  if (BaseAddress == mLpssPciDeviceList[BusNo].Bar0) {
+    MmioWrite32 (BaseAddress + R_IC_TAR, SlaveAddress);
+    *I2CBaseAddress = BaseAddress;
+    return EFI_SUCCESS;
+  }
+
+  Status = ProgramPciLpssI2C (BusNo);
+  if (Status != EFI_SUCCESS) {
+    DEBUG((DEBUG_ERROR, "ProgramPciLpssI2C failed ! %r\r\n", Status));
+    return Status;
+  }
+
+  BaseAddress = (UINT32) mLpssPciDeviceList[BusNo].Bar0;
+  DEBUG ((DEBUG_INFO, "I2CBaseAddress = 0x%x \n", BaseAddress));
+
+  NumTries = 10000; // 1 seconds
+  while ((STAT_MST_ACTIVITY == (MmioRead32 (BaseAddress + R_IC_STATUS) & STAT_MST_ACTIVITY))) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if (0 == NumTries) {
+      DEBUG ((DEBUG_ERROR, "Try timeout\r\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  Status = I2cDisable(BaseAddress);
+  DEBUG ((DEBUG_INFO, "I2cDisable Status = %r\r\n", Status));
+  I2cBusFrequencySet(BusNo, BaseAddress, &I2cMode); // Set I2cMode
+
+  MmioWrite32 (BaseAddress + R_IC_INTR_MASK, 0x0);
+  if (0x7f < SlaveAddress) {
+    SlaveAddress = (SlaveAddress & 0x3ff) | IC_TAR_10BITADDR_MASTER;
+  }
+  MmioWrite32 (BaseAddress + R_IC_TAR, SlaveAddress);
+  MmioWrite32 (BaseAddress + R_IC_RX_TL, 0);
+  MmioWrite32 (BaseAddress + R_IC_TX_TL, 0);
+  MmioWrite32 (BaseAddress + R_IC_CON, I2cMode);
+  Status = I2cEnable(BaseAddress);
+
+  DEBUG((DEBUG_INFO, "I2cEnable Status = %r\r\n", Status));
+  MmioRead32 (BaseAddress + R_IC_CLR_TX_ABRT);
+  *I2CBaseAddress = BaseAddress;
+  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;
+  UINT32      Count = 0;
+  UINTN       I2CBaseAddress;
+  UINT8       *ReadPtr;
+
+  //
+  // Read should always after write, so, base address should already be initialized, then get base address directly
+  //
+  I2CBaseAddress = (UINT32) mLpssPciDeviceList[BusNo].Bar0;
+  DEBUG ((DEBUG_INFO, "mLpssPciDeviceList returned base address = 0x%08x\n", I2CBaseAddress));
+
+  Status = EFI_SUCCESS;
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  ReadPtr = ReadBuffer;
+  if (ReadBytes) {
+    ReceiveRequest = ReadBuffer;
+    //DEBUG((DEBUG_INFO,"Read: ---------------%d bytes to RX\r\n", ReceiveDataEnd - ReceiveRequest));
+
+    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadPtr)) {
+      //
+      // Check for NACK
+      //
+      raw_intr_stat = (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+      if (0 != (raw_intr_stat & I2C_INTR_TX_ABRT)) {
+        MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = EFI_DEVICE_ERROR;
+        DEBUG ((DEBUG_ERROR, "TX ABRT ,%d bytes hasn't been transferred\r\n", ReceiveDataEnd - ReceiveRequest));
+        break;
+      }
+      
+      //
+      // Determine if another byte was received
+      //
+      I2cStatus = (UINT16)MmioRead32 (I2CBaseAddress + R_IC_STATUS);
+      if (0 != (I2cStatus & STAT_RFNE)) {
+        ReceiveData = (UINT16)MmioRead32 (I2CBaseAddress + R_IC_DATA_CMD);
+        *ReadPtr++ = (UINT8)ReceiveData;
+        DEBUG ((DEBUG_INFO, "MmioRead32 ,1 byte 0x:%x is received\r\n", ReceiveData));
+      }
+
+      if (ReceiveDataEnd == ReceiveRequest) {
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        Count++;
+        if (Count < 1024) { // sys hung  avoid no ul-pmc device
+          continue; // Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+        } else {
+          break;
+        }
+      }
+      //
+      // Wait until a read request will fit
+      //
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        MicroSecondDelay (10);
+        continue;
+      }
+      //
+      // Issue the next read request
+      //
+      if (End && Start) {
+        MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start) {
+        MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_RESTART);
+      } else if (End && !Start) {
+        MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
+      } else if (!End && !Start) {
+        MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
+      }
+      MicroSecondDelay (FIFO_WRITE_DELAY); //wait after send 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;
+  UINT32      Count=0;
+  UINTN       I2CBaseAddress;
+
+  Status = I2CInit (BusNo, SlaveAddress, &I2CBaseAddress);
+  if (Status != EFI_SUCCESS) {
+    DEBUG ((DEBUG_ERROR, "I2CInit failed ! %r\r\n", Status));
+    return Status;
+  }
+  DEBUG ((DEBUG_INFO, "I2CInit returned base address = 0x%08x\n", I2CBaseAddress));
+  
+  TransmitPtr = WriteBuffer;
+  TransmitEnd = &WriteBuffer [WriteBytes];
+  if (WriteBytes) {
+    raw_intr_stat = (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+    if (0 != (raw_intr_stat & I2C_INTR_TX_ABRT)) {
+      MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+      DEBUG ((DEBUG_ERROR, "%a(#%d) - raw_intr_stat = %04x\n", __FUNCTION__, __LINE__, TransmitEnd, TransmitPtr, raw_intr_stat));
+    }
+
+    //DEBUG ((DEBUG_INFO, "Write: --------------%d bytes to TX\r\n", TransmitEnd - WriteBuffer));
+    while (TransmitEnd > TransmitPtr) {
+      I2cStatus = MmioRead32 (I2CBaseAddress + R_IC_STATUS);
+      raw_intr_stat = (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+      if (0 != (raw_intr_stat & I2C_INTR_TX_ABRT)) {
+        MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = EFI_DEVICE_ERROR;
+        DEBUG ((DEBUG_ERROR, "%a(#%d) - TX ABRT TransmitEnd:0x%x WritePtr:0x%x\r\n", __FUNCTION__, __LINE__, TransmitEnd, TransmitPtr));
+        break;
+      }
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        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 = MmioWrite16 (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);
+      //
+      // Time out
+      //
+      while (1) {
+        raw_intr_stat = MmioRead16 (I2CBaseAddress + R_IC_RAW_INTR_STAT);
+        if (0 != ( raw_intr_stat & I2C_INTR_TX_ABRT)) {
+          MmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+          Status = EFI_DEVICE_ERROR;
+          DEBUG ((DEBUG_ERROR, "TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", TransmitEnd, WriteBuffer));
+        }
+        if (0 == MmioRead16(I2CBaseAddress + R_IC_TXFLR)) break;
+
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        Count++;
+        if (Count < 1024) { //to avoid sys hung without ul-pmc device on RVP
+          continue; //Waiting the last request to get data and make (ReceiveDataEnd > ReadBuffer) =TRUE.
+        } else {
+          DEBUG ((DEBUG_ERROR, "hardware timeout, 1024 times try!\r\n"));
+          Status = EFI_TIMEOUT;
+          break;
+        }
+      }//while( 1 )
+
+    }
+
+  }
+  if (EFI_ERROR (Status))
+    DEBUG ((DEBUG_ERROR, "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;
+
+  //DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset));
+  Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FALSE);
+  if (!EFI_ERROR (Status)) {
+    Status = ByteReadI2C_Basic (BusNo, SlaveAddress, ReadBytes, ReadBuffer, TRUE, TRUE);
+  } else {
+    DEBUG ((DEBUG_ERROR, "ByteReadI2C/ByteWriteI2C_Basic: %r\n", Status));
+  }
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ByteReadI2C: %r\n", Status));
+  }
+
+  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;
+
+  //DEBUG ((EFI_D_INFO, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
+  Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FALSE);
+  if (!EFI_ERROR (Status)) {
+    Status = ByteWriteI2C_Basic (BusNo, SlaveAddress, WriteBytes, WriteBuffer, FALSE, TRUE);
+  } else {
+    DEBUG ((DEBUG_ERROR, "ByteWriteI2C/ByteWriteI2C_Basic: %r\n", Status));
+  }
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "ByteWriteI2C: %r\n", Status));
+  }
+
+  return Status;
+}
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.inf
new file mode 100644
index 0000000000..81fe55a400
--- /dev/null
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.inf
@@ -0,0 +1,50 @@
+### @file
+# Dxe library for I2C bus driver.
+#
+#@copyright
+# Copyright (c) 2010 - 2018 Intel Corporation. All rights reserved
+#
+#  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                      = I2CLib
+  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2CLib
+#  CONSTRUCTOR                    = IntelI2CLibConstructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+  I2CLib.c
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  TimerLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  BroxtonSiPkg/BroxtonSiPkg.dec
+
+[Protocols]
+
+[Pcd]
+  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress   ## SOMETIMES_CONSUMES
+  gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress          ## SOMETIMES_CONSUMES
+
+
+
diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
index d15170a35c..ad154d57e0 100644
--- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
+++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLibPei.c
@@ -1,7 +1,7 @@
 /** @file
   Pei library for I2C bus driver.
 
-  Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2014 - 2018, 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
@@ -114,7 +114,7 @@ IntelI2CPeiLibConstructor (
 **/
 EFI_STATUS
 ProgramPciLpssI2C (
-  VOID
+  IN UINT8        BusNo
   )
 {
   UINT32       PmcBase;
@@ -387,7 +387,7 @@ I2CInit (
     //
     // Need to enable the I2C PCI device
     //
-    ProgramPciLpssI2C ();
+    ProgramPciLpssI2C (BusNo);
 
     I2CBaseAddress = (UINT32) (LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TMP_BAR0_DELTA));
     if (DebugFlag) DEBUG ((DEBUG_INFO, "I2CBaseAddress = 0x%x \n", I2CBaseAddress));
-- 
2.14.1.windows.1



                 reply	other threads:[~2018-07-26  3:54 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180726035440.15832-1-david.wei@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox