Revision: 17545
          http://sourceforge.net/p/edk2/code/17545
Author:   zwei4
Date:     2015-06-02 01:45:22 +0000 (Tue, 02 Jun 2015)
Log Message:
-----------
Add Sample I2C Library for Baytrail I2C Controller.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei  <[email protected]>
Reviewed-by: Tim He <[email protected]> 

Added Paths:
-----------
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
    branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Include/Library/I2CLib.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Include/Library/I2CLib.h             
                (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Include/Library/I2CLib.h     
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,64 @@
+/** @file
+  Interface Definitions for I2C Lib.
+  
+  Copyright (c) 2004  - 2015, 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 that 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 <Uefi.h>
+#include <Library/IoLib.h>
+
+#ifndef I2C_LIB_HEADER_H
+#define I2C_LIB_HEADER_H
+
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2C(
+  IN  UINT8 BusNo, 
+  IN  UINT8 SlaveAddress, 
+  IN  UINT8 Offset,  
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/  
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 BusNo, 
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  );
+
+#endif

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c           
                (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLib.c   
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,741 @@
+/** @file
+  Functions for accessing I2C registers.
+  
+  Copyright (c) 2004  - 2015, 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 that 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/TimerLib.h>
+#include <PchRegs/PchRegsPcu.h> 
+#include <PchRegs.h>
+#include <PlatformBaseAddresses.h>
+#include <PchRegs/PchRegsLpss.h> 
+#include <Library/I2CLib.h>
+#include <Protocol/GlobalNvsArea.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <I2CRegs.h>
+
+#define GLOBAL_NVS_OFFSET(Field)    
(UINTN)((CHAR8*)&((EFI_GLOBAL_NVS_AREA*)0)->Field - (CHAR8*)0)
+
+#define PCIEX_BASE_ADDRESS  0xE0000000
+#define PCI_EXPRESS_BASE_ADDRESS ((VOID *) (UINTN) PCIEX_BASE_ADDRESS)
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+         ((UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+         (UINTN)(Bus << 20) + \
+         (UINTN)(Device << 15) + \
+         (UINTN)(Function << 12) + \
+         (UINTN)(Register) \
+        )
+#define PCI_D31F0_REG_BASE             PCIEX_BASE_ADDRESS + (UINT32) (31 << 15)
+
+typedef struct _LPSS_PCI_DEVICE_INFO {
+  UINTN        Segment;
+  UINTN        BusNum;
+  UINTN        DeviceNum;
+  UINTN        FunctionNum;
+  UINTN        Bar0;
+  UINTN        Bar1;
+} LPSS_PCI_DEVICE_INFO;
+
+LPSS_PCI_DEVICE_INFO  mLpssPciDeviceList[] = {
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_DMAC1, 
PCI_FUNCTION_NUMBER_PCH_LPSS_DMAC, 0xFE900000, 0xFE908000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C0, 0xFE910000, 0xFE918000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C1, 0xFE920000, 0xFE928000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C2, 0xFE930000, 0xFE938000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C3, 0xFE940000, 0xFE948000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C4, 0xFE950000, 0xFE958000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C5, 0xFE960000, 0xFE968000},
+  {0, DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPSS_I2C,   
PCI_FUNCTION_NUMBER_PCH_LPSS_I2C6, 0xFE970000, 0xFE978000}
+};
+
+#define LPSS_PCI_DEVICE_NUMBER  
sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI_DEVICE_INFO)
+
+STATIC UINTN mI2CBaseAddress = 0;
+STATIC UINT16 mI2CSlaveAddress = 0;
+
+UINT16 mI2cMode=B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE ;
+
+UINTN mI2cNvsBaseAddress[] = {
+        GLOBAL_NVS_OFFSET(LDMA2Addr),
+        GLOBAL_NVS_OFFSET(I2C1Addr),
+        GLOBAL_NVS_OFFSET(I2C2Addr),
+        GLOBAL_NVS_OFFSET(I2C3Addr),
+        GLOBAL_NVS_OFFSET(I2C4Addr),
+        GLOBAL_NVS_OFFSET(I2C5Addr),
+        GLOBAL_NVS_OFFSET(I2C6Addr),
+        GLOBAL_NVS_OFFSET(I2C7Addr)
+      };
+
+/**
+  This function get I2Cx controller base address (BAR0).
+
+  @param I2cControllerIndex  Bus Number of I2C controller.
+
+  @return I2C BAR. 
+**/
+UINTN
+GetI2cBarAddr(
+  IN    UINT8 I2cControllerIndex
+  )
+{
+  EFI_STATUS           Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
+  UINTN  AcpiBaseAddr;
+  UINTN  PciMmBase=0;
+
+  ASSERT(gBS!=NULL);
+
+  Status = gBS->LocateProtocol (
+                  &gEfiGlobalNvsAreaProtocolGuid,
+                  NULL,
+                  &GlobalNvsArea
+                  );
+                  
+  //
+  // PCI mode from PEI ( Global NVS is not ready).
+  //
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_INFO, "GetI2cBarAddr() gEfiGlobalNvsAreaProtocolGuid:%r\n", 
Status));
+    //
+    // Global NVS is not ready.
+    //
+    return 0;
+  }
+
+  AcpiBaseAddr =  *(UINTN*)((CHAR8*)GlobalNvsArea->Area + 
mI2cNvsBaseAddress[I2cControllerIndex + 1]);
+  
+  //
+  //PCI mode from DXE (global NVS protocal) to LPSS OnReadytoBoot(swith to 
ACPI).
+  //
+  if(AcpiBaseAddr==0) {
+    PciMmBase = MmPciAddress (
+                  mLpssPciDeviceList[I2cControllerIndex + 1].Segment,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].BusNum,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum,
+                  mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum,
+                  0
+                  );
+    DEBUG((EFI_D_ERROR, "\nGetI2cBarAddr() I2C Device %x %x %x 
PciMmBase:%x\n", \
+           mLpssPciDeviceList[I2cControllerIndex + 1].BusNum, \
+           mLpssPciDeviceList[I2cControllerIndex + 1].DeviceNum, \
+           mLpssPciDeviceList[I2cControllerIndex + 1].FunctionNum, PciMmBase));
+
+    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)    {
+      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& 
B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Get the address allocted.
+        //
+        mLpssPciDeviceList[I2cControllerIndex + 1].Bar0=MmioRead32 
(PciMmBase+R_PCH_LPSS_I2C_BAR);     
+        mLpssPciDeviceList[I2cControllerIndex + 1].Bar1=MmioRead32 
(PciMmBase+R_PCH_LPSS_I2C_BAR1);
+      }
+    }
+    AcpiBaseAddr =mLpssPciDeviceList[I2cControllerIndex+1].Bar0;
+  }
+  
+  //
+  // ACPI mode from BDS: LPSS OnReadytoBoot
+  //
+  else {
+    DEBUG ((EFI_D_INFO, "GetI2cBarAddr() NVS Varialable is updated by this LIB 
or LPSS  \n"));
+  }
+  
+  DEBUG ((EFI_D_INFO, "GetI2cBarAddr() I2cControllerIndex+1 0x%x 
AcpiBaseAddr:0x%x \n", (I2cControllerIndex + 1), AcpiBaseAddr));
+  return AcpiBaseAddr;
+}
+
+
+/**
+  This function enables I2C controllers.
+
+  @param I2cControllerIndex  Bus Number of I2C controllers.
+
+  @return Result of the I2C initialization.
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  IN  UINT8 I2cControllerIndex
+  )
+{
+  UINT32                        PmcBase;
+  UINTN                         PciMmBase=0;
+  EFI_STATUS                    Status;
+  EFI_GLOBAL_NVS_AREA_PROTOCOL  *GlobalNvsArea;
+
+  UINT32 PmcFunctionDsiable[]= {
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6,
+    B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7
+  };
+
+  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Start\n"));
+
+  //
+  // Set the VLV Function Disable Register to ZERO
+  //
+  PmcBase = MmioRead32 (PCI_D31F0_REG_BASE + R_PCH_LPC_PMC_BASE) & 
B_PCH_LPC_PMC_BASE_BAR;
+  
if(MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)&PmcFunctionDsiable[I2cControllerIndex])
 {
+    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End:I2C[%x] is 
disabled\n",I2cControllerIndex));
+    return EFI_NOT_READY;
+  }
+  
+  DEBUG ((EFI_D_INFO, 
"ProgramPciLpssI2C()------------I2cControllerIndex=%x,PMC=%x\n",I2cControllerIndex,MmioRead32(PmcBase+R_PCH_PMC_FUNC_DIS)));
+
+  {
+    PciMmBase = MmPciAddress (
+                  mLpssPciDeviceList[I2cControllerIndex+1].Segment,
+                  mLpssPciDeviceList[I2cControllerIndex+1].BusNum,
+                  mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum,
+                  mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum,
+                  0
+                  );
+                  
+    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  %x %x %x 
PciMmBase:%x\n", \
+           mLpssPciDeviceList[I2cControllerIndex+1].BusNum, \
+           mLpssPciDeviceList[I2cControllerIndex+1].DeviceNum, \
+           mLpssPciDeviceList[I2cControllerIndex+1].FunctionNum, PciMmBase));
+
+    if (MmioRead32 (PciMmBase) != 0xFFFFFFFF)     {
+      if((MmioRead32 (PciMmBase+R_PCH_LPSS_I2C_STSCMD)& 
B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Get the address allocted.
+        //
+        mLpssPciDeviceList[I2cControllerIndex+1].Bar0=MmioRead32 
(PciMmBase+R_PCH_LPSS_I2C_BAR);     
+        mLpssPciDeviceList[I2cControllerIndex+1].Bar1=MmioRead32 
(PciMmBase+R_PCH_LPSS_I2C_BAR1);
+        DEBUG((EFI_D_ERROR, "ProgramPciLpssI2C() bar0:0x%x 
bar1:0x%x\n",mLpssPciDeviceList[I2cControllerIndex+1].Bar0, 
mLpssPciDeviceList[I2cControllerIndex+1].Bar1));
+      } else {
+        
+        //
+        // Program BAR 0
+        //
+        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & 
B_PCH_LPSS_I2C_BAR_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar0) && 
(mLpssPciDeviceList[I2cControllerIndex+1].Bar0 != 0));
+        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), (UINT32) 
(mLpssPciDeviceList[I2cControllerIndex+1].Bar0 & B_PCH_LPSS_I2C_BAR_BA));
+       
+        //
+        // Program BAR 1
+        //
+        ASSERT (((mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & 
B_PCH_LPSS_I2C_BAR1_BA) == mLpssPciDeviceList[I2cControllerIndex+1].Bar1) && 
(mLpssPciDeviceList[I2cControllerIndex+1].Bar1 != 0));
+        MmioWrite32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR1), (UINT32) 
(mLpssPciDeviceList[I2cControllerIndex+1].Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
+        
+        //
+        // Bus Master Enable & Memory Space Enable
+        //
+        MmioOr32 ((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), (UINT32) 
(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
+        ASSERT (MmioRead32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0) != 
0xFFFFFFFF);
+      }
+      
+      //
+      // Release Resets
+      //
+      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + 
R_PCH_LPIO_I2C_MEM_RESETS,(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | 
B_PCH_LPIO_I2C_MEM_RESETS_APB));
+      
+      //
+      // Activate Clocks
+      //
+      MmioWrite32 (mLpssPciDeviceList[I2cControllerIndex+1].Bar0 + 
R_PCH_LPSS_I2C_MEM_PCP,0x80020003);//No use for A0
+
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
+    }
+    
+    //
+    // BDS: already switched to ACPI mode
+    //
+    else {
+      ASSERT(gBS!=NULL);
+      Status = gBS->LocateProtocol (
+                      &gEfiGlobalNvsAreaProtocolGuid,
+                      NULL,
+                      &GlobalNvsArea
+                      );
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "GetI2cBarAddr() 
gEfiGlobalNvsAreaProtocolGuid:%r\n", Status));
+        //
+        // gEfiGlobalNvsAreaProtocolGuid is not ready.
+        //
+        return 0;
+      }
+      mLpssPciDeviceList[I2cControllerIndex + 1].Bar0 = 
*(UINTN*)((CHAR8*)GlobalNvsArea->Area + mI2cNvsBaseAddress[I2cControllerIndex + 
1]);
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C(): is switched to ACPI 0x:%x 
\n",mLpssPciDeviceList[I2cControllerIndex + 1].Bar0));
+    }
+  }
+  
+  DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C disabling.
+**/
+RETURN_STATUS
+I2cDisable (
+  VOID
+  )
+{ 
+  //
+  // 0.1 seconds
+  //
+  UINT32 NumTries = 10000;
+  
+  MmioWrite32 ( mI2CBaseAddress + R_IC_ENABLE, 0 );
+  while ( 0 != ( MmioRead32 ( mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries) {
+      return RETURN_NOT_READY;
+    }
+  }
+  
+  return RETURN_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C disabling.
+**/
+RETURN_STATUS
+I2cEnable (
+  VOID
+  )
+{
+  //
+  // 0.1 seconds
+  //
+  UINT32 NumTries = 10000;
+  
+  MmioWrite32 (mI2CBaseAddress + R_IC_ENABLE, 1);
+  
+  while (0 == (MmioRead32 (mI2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries){
+       return RETURN_NOT_READY;
+    }
+  }
+  
+  return RETURN_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param VOID.
+
+  @return Result of the I2C enabling.
+**/
+RETURN_STATUS
+I2cBusFrequencySet (
+  IN UINTN BusClockHertz
+  )
+{
+  DEBUG((EFI_D_INFO,"InputFreq BusClockHertz: %d\r\n",BusClockHertz));
+  
+  //
+  //  Set the 100 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)0x214 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)0x272 );
+  
+  //
+  //  Set the 400 KHz clock divider according to SV result and I2C spec
+  //
+  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)0x50 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)0xAD );
+
+  switch ( BusClockHertz ) {
+    case 100 * 1000:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x40);//100K
+      mI2cMode = V_SPEED_STANDARD;
+      break;
+    case 400 * 1000:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x32);//400K
+      mI2cMode = V_SPEED_FAST;
+      break;
+    default:
+      MmioWrite32 ( mI2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x09);//3.4M
+      mI2cMode = V_SPEED_HIGH;
+  }
+
+  //
+  //  Select the frequency counter,
+  //  Enable restart condition,
+  //  Enable master FSM, disable slave FSM.
+  //
+  mI2cMode |= B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Initializes the host controller to execute I2C commands.
+
+  @param I2cControllerIndex Index of I2C controller in LPSS device. 0 
represents I2C0, which is PCI function 1 of LPSS device.   
+                                
+  @return EFI_SUCCESS       Opcode initialization on the I2C host controller 
completed.
+  @return EFI_DEVICE_ERROR  Device error, operation failed.
+**/
+EFI_STATUS
+I2CInit (
+  IN  UINT8  I2cControllerIndex,
+  IN  UINT16 SlaveAddress
+  )
+{
+  EFI_STATUS Status=RETURN_SUCCESS;
+  UINT32    NumTries = 0;
+  UINTN    GnvsI2cBarAddr=0;
+  
+  //
+  // Verify the parameters
+  //
+  if ((1023 < SlaveAddress) || (6 < I2cControllerIndex)) {
+    Status =  RETURN_INVALID_PARAMETER;
+    DEBUG((EFI_D_INFO,"I2CInit Exit with RETURN_INVALID_PARAMETER\r\n"));
+    return Status;
+  }
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
+  mI2CSlaveAddress = SlaveAddress;
+
+  //
+  // 1.PEI: program and init ( before pci enumeration).
+  // 2.DXE:update address and re-init ( after pci enumeration).
+  // 3.BDS:update ACPI address and re-init ( after acpi mode is enabled).
+  //
+  if(mI2CBaseAddress == mLpssPciDeviceList[I2cControllerIndex + 1].Bar0) {
+    
+    //
+    // I2CInit is already  called.
+    //
+    GnvsI2cBarAddr=GetI2cBarAddr(I2cControllerIndex);
+    
+    if((GnvsI2cBarAddr == 0)||(GnvsI2cBarAddr == mI2CBaseAddress)) {
+      DEBUG((EFI_D_INFO,"I2CInit Exit with mI2CBaseAddress:%x == 
[%x].Bar0\r\n",mI2CBaseAddress,I2cControllerIndex+1));
+      return RETURN_SUCCESS;
+    }
+  }
+  
+  Status=ProgramPciLpssI2C(I2cControllerIndex);
+  if(Status!=EFI_SUCCESS) {
+    return Status;
+  }
+
+
+  mI2CBaseAddress = (UINT32) mLpssPciDeviceList[I2cControllerIndex + 1].Bar0;
+  DEBUG ((EFI_D_ERROR, "mI2CBaseAddress = 0x%x \n",mI2CBaseAddress));
+  
+  //
+  // 1 seconds.
+  //
+  NumTries = 10000; 
+  while ((1 == ( MmioRead32 ( mI2CBaseAddress + R_IC_STATUS) & 
STAT_MST_ACTIVITY ))) {
+    MicroSecondDelay(10);
+    NumTries --;
+    if(0 == NumTries) {
+      DEBUG((EFI_D_INFO, "Try timeout\r\n"));
+      return RETURN_DEVICE_ERROR;
+    }
+  }
+  
+  Status = I2cDisable();
+  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
+  I2cBusFrequencySet(400 * 1000);
+
+  MmioWrite32(mI2CBaseAddress + R_IC_INTR_MASK, 0x0);
+  if (0x7f < SlaveAddress )
+    SlaveAddress = ( SlaveAddress & 0x3ff ) | IC_TAR_10BITADDR_MASTER;
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TAR, (UINT16)SlaveAddress );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_RX_TL, 0);
+  MmioWrite32 ( mI2CBaseAddress + R_IC_TX_TL, 0 );
+  MmioWrite32 ( mI2CBaseAddress + R_IC_CON, mI2cMode);
+  Status = I2cEnable();
+
+  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
+  MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex             I2C Bus no to which the I2C device 
has been connected
+  @param  SlaveAddress      Device Address from which the byte value has to be 
read
+  @param  Offset            Offset from which the data has to be read
+  @param  *Byte             Address to which the value read has to be stored
+  @param  Start               Whether a RESTART is issued before the byte is 
sent or received
+  @param  End                 Whether STOP is generated after a data byte is 
sent or received  
+                                  
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  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 RawIntrStat;
+  UINT32 Count=0;
+
+  Status = EFI_SUCCESS;
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  if( ReadBytes ) {
+
+    ReceiveRequest = ReadBuffer;
+    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd 
- ReceiveRequest));
+
+    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) 
{
+      
+      //
+      //  Check for NACK
+      //
+      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
+      if ( 0 != ( RawIntrStat & I2C_INTR_TX_ABRT )) {
+        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT );
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_INFO,"TX ABRT ,%d bytes hasn't been 
transferred\r\n",ReceiveDataEnd - ReceiveRequest));
+        break;
+      }
+      
+      //
+      // Determine if another byte was received
+      //
+      I2cStatus = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
+      if (0 != ( I2cStatus & STAT_RFNE )) {
+        ReceiveData = (UINT16)MmioRead32 ( mI2CBaseAddress + R_IC_DATA_CMD );
+        *ReadBuffer++ = (UINT8)ReceiveData;
+        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is 
received\r\n",ReceiveData));
+      }
+
+      if(ReceiveDataEnd == ReceiveRequest) {
+        MicroSecondDelay ( FIFO_WRITE_DELAY );
+        
DEBUG((EFI_D_INFO,"ReceiveDataEnd==ReceiveRequest------------%x\r\n",I2cStatus 
& STAT_RFNE));
+        Count++;
+        if(Count<1024) {
+          //
+          // To avoid sys hung  without ul-pmc device  on RVP,
+          // waiting the last request to get data and make (ReceiveDataEnd > 
ReadBuffer) =TRUE.
+          //
+          continue;
+        } else {
+          break;
+        }
+      }
+      
+      //
+      //  Wait until a read request will fit.
+      //
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        DEBUG((EFI_D_INFO,"Wait until a read request will fit\r\n"));
+        MicroSecondDelay (10);
+        continue;
+      }
+      
+      //
+      //  Issue the next read request.
+      //
+      if(End && Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, 
B_READ_CMD|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, 
B_READ_CMD|B_CMD_RESTART);
+      } else if (End && !Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP);
+      } else if (!End && !Start) {
+        MmioWrite32 ( mI2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD);
+      }
+      MicroSecondDelay (FIFO_WRITE_DELAY);
+
+      ReceiveRequest += 1;
+    }
+  }
+  
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+  @param  Start               Whether a RESTART is issued before the byte is 
sent or received
+  @param  End                 Whether STOP is generated after a data byte is 
sent or received  
+                                    
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT8 *TransmitEnd;
+  UINT16 RawIntrStat;
+  UINT32 Count=0;
+
+  Status = EFI_SUCCESS;
+
+  Status=I2CInit(I2cControllerIndex, SlaveAddress);
+  if(Status!=EFI_SUCCESS)
+    return Status;
+
+  TransmitEnd = &WriteBuffer[WriteBytes];
+  if( WriteBytes ) {
+    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n",TransmitEnd - 
WriteBuffer));
+    while (TransmitEnd > WriteBuffer) {
+      I2cStatus = MmioRead32 (mI2CBaseAddress + R_IC_STATUS);
+      RawIntrStat = (UINT16)MmioRead32 (mI2CBaseAddress + R_IC_RawIntrStat);
+      if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
+        MmioRead32 ( mI2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", 
TransmitEnd, WriteBuffer));
+        break;
+      }
+      if (0 == (I2cStatus & STAT_TFNF)) {
+        //
+        // If TX not full , will  send cmd  or continue to wait
+        //
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        continue;
+      }
+
+      if(End && Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, 
(*WriteBuffer++)|B_CMD_RESTART|B_CMD_STOP);
+      } else if (!End && Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, 
(*WriteBuffer++)|B_CMD_RESTART);
+      } else if (End && !Start) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, 
(*WriteBuffer++)|B_CMD_STOP);
+      } else if (!End && !Start ) {
+        MmioWrite32 (mI2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++));
+      }
+      
+      //
+      // Add a small delay to work around some odd behavior being seen.  
Without this delay bytes get dropped.
+      //
+      MicroSecondDelay ( FIFO_WRITE_DELAY );//wait after send cmd
+      
+      //
+      // Time out
+      //
+      while(1) {
+        RawIntrStat = MmioRead16 ( mI2CBaseAddress + R_IC_RawIntrStat );
+        if (0 != ( RawIntrStat & I2C_INTR_TX_ABRT)) {
+          MmioRead16 (mI2CBaseAddress + R_IC_CLR_TX_ABRT);
+          Status = RETURN_DEVICE_ERROR;
+          DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", 
TransmitEnd, WriteBuffer));
+        }
+        if(0 == MmioRead16(mI2CBaseAddress + R_IC_TXFLR)) break;
+
+        MicroSecondDelay (FIFO_WRITE_DELAY);
+        Count++;
+        if(Count<1024) {
+          //
+          // to avoid sys hung without ul-pmc device on RVP.
+          // Waiting the last request to get data and make (ReceiveDataEnd > 
ReadBuffer) =TRUE.
+          //
+          continue;
+        } else {
+          break;
+        }
+      }//while( 1 )
+    }
+
+  }
+
+  return Status;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  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 = ByteWriteI2CBasic(I2cControllerIndex, 
SlaveAddress,1,&Offset,TRUE,FALSE);
+  Status = ByteReadI2CBasic(I2cControllerIndex, 
SlaveAddress,ReadBytes,ReadBuffer,TRUE,TRUE);
+
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  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 = ByteWriteI2CBasic(I2cControllerIndex, 
SlaveAddress,1,&Offset,TRUE,FALSE);
+  Status = ByteWriteI2CBasic(I2cControllerIndex, 
SlaveAddress,WriteBytes,WriteBuffer,FALSE,TRUE);
+
+  return Status;
+}

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CLibDxe.inf      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,44 @@
+## @file
+#  Instance of I2C Library.
+#
+#  Copyright (c) 2010 - 2015, 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                      = I2CLib
+  FILE_GUID                      = 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = I2CLib|DXE_DRIVER DXE_RUNTIME_DRIVER 
UEFI_DRIVER UEFI_APPLICATION
+  
+#
+# 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
+  MdeModulePkg/MdeModulePkg.dec
+  Vlv2TbltDevicePkg/PlatformPkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+[Protocols]
+  gEfiGlobalNvsAreaProtocolGuid

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h          
                (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibDxe/I2CRegs.h  
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,132 @@
+/** @file
+  Register Definitions for I2C Driver/PEIM.
+  
+  Copyright (c) 2004  - 2015, 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 that 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_REGS_H
+#define I2C_REGS_H
+
+//
+// FIFO write delay 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_RawIntrStat                ( 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    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
+
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+#define     FIFO_SIZE                         32
+#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_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock 
Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock 
Parameters
+
+#endif
\ No newline at end of file

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h        
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CAccess.h        
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,50 @@
+/** @file
+  Misc Registers Definition.
+  
+  Copyright (c) 2011  - 2015, 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 that 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_
+
+#include "I2CIoLibPei.h"
+
+#define DEFAULT_PCI_BUS_NUMBER_PCH             0
+
+#define PCI_DEVICE_NUMBER_PCH_LPC              31
+#define PCI_FUNCTION_NUMBER_PCH_LPC            0
+
+#define R_PCH_LPC_ACPI_BASE                    0x40            // ABASE, 16bit
+#define R_PCH_LPC_ACPI_BASEADR                 0x400           // ABASE, 16bit
+#define B_PCH_LPC_ACPI_BASE_EN                 BIT1            // Enable Bit
+#define B_PCH_LPC_ACPI_BASE_BAR                0x0000FF80      // Base 
Address, 128 Bytes
+#define V_PCH_ACPI_PM1_TMR_MAX_VAL             0x1000000       // The timer is 
24 bit overflow
+#define B_PCH_ACPI_PM1_TMR_VAL                 0xFFFFFF        // The timer 
value mask
+
+#define R_PCH_ACPI_PM1_TMR                     0x08            // Power 
Management 1 Timer
+#define V_PCH_ACPI_PM1_TMR_FREQUENCY           3579545         // Timer 
Frequency
+
+
+#define PchLpcPciCfg8(Register) I2CLibPeiMmioRead8 (MmPciAddress (0, 
DEFAULT_PCI_BUS_NUMBER_PCH, PCI_DEVICE_NUMBER_PCH_LPC, 0, Register))
+
+#define PCIEX_BASE_ADDRESS                     0xE0000000
+#define PCI_EXPRESS_BASE_ADDRESS               ((VOID *) (UINTN) 
PCIEX_BASE_ADDRESS)
+
+#define MmPciAddress( Segment, Bus, Device, Function, Register ) \
+  ( (UINTN)PCI_EXPRESS_BASE_ADDRESS + \
+    (UINTN)(Bus << 20) + \
+    (UINTN)(Device << 15) + \
+    (UINTN)(Function << 12) + \
+    (UINTN)(Register) \
+  )
+#endif
+

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.c      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,52 @@
+/** @file
+  MicroSecondDelay implementation of ACPI Timer.
+  
+  Copyright (c) 2007 - 2015, 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 that 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.
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return EFI_STATUS
+
+**/
+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, &StallPpi);
+  ASSERT(!EFI_ERROR(Status));
+
+  StallPpi->Stall (PeiServices, StallPpi, MicroSeconds);
+
+  return EFI_SUCCESS;
+}

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CDelayPei.h      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,36 @@
+/** @file
+  MicroSecondDelay implementation of ACPI Timer.
+
+  Copyright (c) 2006 - 2015, 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.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return MicroSeconds
+
+**/
+EFI_STATUS
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  );
+
+#endif

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.c      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,184 @@
+/** @file
+  Functions for access I2C MMIO register.
+
+  Copyright (c) 2006 - 2015, 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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  )
+{
+  ASSERT ((Address & 3) == 0);
+  *(volatile UINT32*)Address = Value;
+  return Value;
+}
+
+/**
+  OR a 32-bit MMIO register.
+
+  OR 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  Address The MMIO register to write OR.
+  @param  Value   The value to OR to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  )
+{
+  return I2CLibPeiMmioWrite32 (Address, I2CLibPeiMmioRead32(Address) | OrData);
+}
+
+

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CIoLibPei.h      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,159 @@
+/** @file
+  Functions for access I2C MMIO register.
+
+  Copyright (c) 2006 - 2015, 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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+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  Address The MMIO register to read.
+
+  @return The 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  Address The MMIO register to write.
+  @param  Value   The value to write to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioWrite32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    Value
+  );
+
+
+/**
+  OR a 32-bit MMIO register.
+
+  OR 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  Address The MMIO register to write OR.
+  @param  Value   The value to OR to the MMIO register.
+
+  @return Value.
+
+**/
+UINT32
+EFIAPI
+I2CLibPeiMmioOr32 (
+  IN      UINTN                     Address,
+  IN      UINT32                    OrData
+  );
+
+
+#endif

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c        
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.c        
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,644 @@
+/** @file
+  I2C PEI Lib Instance.
+
+  Copyright (c) 1999- 2015, 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 "I2CLibPei.h"
+#include <PlatformBaseAddresses.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/HobLib.h>
+#include <PchRegs/PchRegsPcu.h> 
+#include <PchRegs/PchRegsLpss.h> 
+
+#define LPSS_PCI_DEVICE_NUMBER  8
+
+#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock 
Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock 
Parameters
+
+#define PEI_TEPM_LPSS_DMA_BAR                     0xFE900000
+#define PEI_TEPM_LPSS_I2C0_BAR                    0xFE910000
+#define PCI_CONFIG_SPACE_SIZE                     0x10000
+
+EFI_GUID  mI2CPeiInitGuid = {
+  0x96DED71A, 0xB9E7, 0x4EAD, 0x96, 0x2C, 0x01, 0x69, 0x3C, 0xED, 0x2A, 0x64
+};
+
+
+UINT16 I2CGPIO[]= {
+  //
+  // 19.1.6  I2C0
+  // I2C0_SDA-OD-O -    write 0x2003CC81 to IOBASE + 0x0210
+  // I2C0_SCL-OD-O -    write 0x2003CC81 to IOBASE + 0x0200
+  //
+  0x0210,
+  0x0200,
+
+  //
+  // 19.1.7  I2C1
+  // I2C1_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01F0
+  // I2C1_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01E0
+  //
+  0x01F0,
+  0x01E0,
+
+  //
+  // 19.1.8  I2C2
+  // I2C2_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01D0
+  // I2C2_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01B0
+  //
+  0x01D0,
+  0x01B0,
+
+  //
+  // 19.1.9  I2C3
+  // I2C3_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0190
+  // I2C3_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x01C0
+  // 
+  0x0190,
+  0x01C0,
+
+  //
+  // 19.1.10 I2C4
+  // I2C4_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x01A0
+  // I2C4_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0170
+  //
+  0x01A0,
+  0x0170,
+
+  // 
+  // 19.1.11 I2C5
+  // I2C5_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0150
+  // I2C5_SCL-OD-O/I - write 0x2003CC81 to IOBASE + 0x0140
+  // 
+  0x0150,
+  0x0140,
+
+  //
+  // 19.1.12 I2C6
+  // I2C6_SDA-OD-O/I - write 0x2003CC81 to IOBASE + 0x0180
+  // I2C6_SCL-OD-O/I -  write 0x2003CC81 to IOBASE + 0x0160
+  // 
+  0x0180,
+  0x0160
+};
+
+/**
+  Constructor of this library.
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IntelI2CPeiLibConstructor (
+  IN EFI_PEI_FILE_HANDLE     FileHandle,
+  IN CONST EFI_PEI_SERVICES  **PeiServices
+  )
+{
+  UINTN Index;
+  
+  for (Index = 0; Index < sizeof(I2CGPIO)/sizeof(UINT16); Index ++) {
+    I2CLibPeiMmioWrite32(IO_BASE_ADDRESS+I2CGPIO[Index], 0x2003CC81);
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Programe all I2C controllers on LPSS. 
+  
+  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+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 VLV Function Disable Register to ZERO
+  //
+  PmcBase         = I2CLibPeiMmioRead32(PciD31F0RegBase + R_PCH_LPC_PMC_BASE) 
& B_PCH_LPC_PMC_BASE_BAR;
+  
+  if(I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)&
+      (B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2
+       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 | 
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5
+       | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)) {
+    I2CLibPeiMmioWrite32(
+      PmcBase+R_PCH_PMC_FUNC_DIS,
+      I2CLibPeiMmioRead32(PmcBase + R_PCH_PMC_FUNC_DIS)& \
+      ~(B_PCH_PMC_FUNC_DIS_LPSS2_FUNC1 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC2 \
+        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC3 | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC4 \
+        | B_PCH_PMC_FUNC_DIS_LPSS2_FUNC5 | 
B_PCH_PMC_FUNC_DIS_LPSS2_FUNC6|B_PCH_PMC_FUNC_DIS_LPSS2_FUNC7)
+      );
+    DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() enable all I2C controllers\n"));
+  }
+
+  for(Index = 0; Index < LPSS_PCI_DEVICE_NUMBER; Index ++) {
+
+    PciMmBase = MmPciAddress (
+                  0,
+                  DEFAULT_PCI_BUS_NUMBER_PCH,
+                  PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
+                  Index,
+                  0
+                  );
+    DevID =  I2CLibPeiMmioRead32(PciMmBase);
+
+    Bar0 = PEI_TEPM_LPSS_DMA_BAR + (Index * PCI_CONFIG_SPACE_SIZE);
+    Bar1 = Bar0 + 0x8000;
+
+    DEBUG((EFI_D_ERROR, "Program Pci Lpss I2C Device  Function=%x 
DevID=%08x\n", Index, DevID));
+    
+    //
+    // Check if device present
+    //
+    if (DevID  != 0xFFFFFFFF)  {
+      if(!(I2CLibPeiMmioRead32 (PciMmBase + R_PCH_LPSS_I2C_STSCMD) & 
B_PCH_LPSS_I2C_STSCMD_MSE)) {
+        //
+        // Program BAR 0
+        //
+        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_BAR), 
(UINT32)(Bar0 & B_PCH_LPSS_I2C_BAR_BA));
+        
+        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x \n",I2CLibPeiMmioRead32 
(PciMmBase+R_PCH_LPSS_I2C_BAR)));
+        
+        //
+        // Program BAR 1
+        //
+        I2CLibPeiMmioWrite32 ((UINTN)(PciMmBase + R_PCH_LPSS_I2C_BAR1), 
(UINT32)(Bar1 & B_PCH_LPSS_I2C_BAR1_BA));
+        DEBUG ((EFI_D_ERROR, "I2CBaseAddress1 = 0x%x 
\n",I2CLibPeiMmioRead32(PciMmBase+R_PCH_LPSS_I2C_BAR1)));
+        
+        //
+        // Bus Master Enable & Memory Space Enable
+        //
+        I2CLibPeiMmioWrite32((UINTN) (PciMmBase + R_PCH_LPSS_I2C_STSCMD), 
(UINT32)(B_PCH_LPSS_I2C_STSCMD_BME | B_PCH_LPSS_I2C_STSCMD_MSE));
+      }
+      
+      //
+      // Release Resets
+      //
+      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPIO_I2C_MEM_RESETS, 
(B_PCH_LPIO_I2C_MEM_RESETS_FUNC | B_PCH_LPIO_I2C_MEM_RESETS_APB));
+      
+      //
+      // Activate Clocks
+      //
+      I2CLibPeiMmioWrite32 (Bar0 + R_PCH_LPSS_I2C_MEM_PCP, 0x80020003);//No 
use for A0
+
+      DEBUG ((EFI_D_INFO, "ProgramPciLpssI2C() Programmed()\n"));
+    }
+
+  }
+  
+  DEBUG ((EFI_D_INFO, "Pei ProgramPciLpssI2C() End\n"));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Disable I2C Bus.
+
+  @param I2cControllerIndex   Index of I2C controller.
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+I2cDisable (
+  IN UINT8 I2cControllerIndex
+  )
+{
+  UINTN  I2CBaseAddress;
+  UINT32 NumTries = 10000;  // 0.1 seconds
+  
+  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE;
+  
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 0);
+  while (0 != ( I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_ENABLE_STATUS ) & 
1)) {
+    MicroSecondDelay (10);
+    NumTries --;
+    if(0 == NumTries) return EFI_NOT_READY;
+  }
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Enable I2C Bus.
+
+  @param I2cControllerIndex   Index of I2C controller.
+
+  @return EFI_SUCCESS
+**/
+EFI_STATUS
+I2cEnable (
+  IN UINT8 I2cControllerIndex
+  )
+{
+  UINTN   I2CBaseAddress;
+  UINT32 NumTries = 10000;  // 0.1 seconds
+  
+  I2CBaseAddress = (UINT32) PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE;
+  I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_ENABLE, 1);
+  while (0 == ( I2CLibPeiMmioRead16 ( 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.
+
+  @param[in] This           Address of the library's I2C context structure
+  @param[in] PlatformData   Address of the platform configuration data
+  @param[in] BusClockHertz  New I2C bus clock frequency in Hertz
+
+  @retval RETURN_SUCCESS      The bus frequency was set successfully.
+  @retval RETURN_UNSUPPORTED  The controller does not support this frequency.
+
+**/
+EFI_STATUS
+I2cBusFrequencySet (
+  IN UINTN   I2CBaseAddress,
+  IN UINTN   BusClockHertz,
+  IN UINT16  *I2cMode
+  )
+{
+  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 I2cControllerIndex Index of I2C controller in LPSS device. 0 
represents I2C0, which is PCI function 1 of LPSS device.   
+                                
+  @return EFI_SUCCESS       Opcode initialization on the I2C host controller 
completed.
+  @return EFI_DEVICE_ERROR  Device error, operation failed.
+**/
+EFI_STATUS
+I2CInit (
+  UINT8 I2cControllerIndex, 
+  UINT16 SlaveAddress
+  )
+{
+  EFI_STATUS   Status;
+  UINT32       NumTries = 0;
+  UINTN        I2CBaseAddress;
+  UINT16       I2cMode;
+  UINTN        PciMmBase=0;
+
+
+  PciMmBase = MmPciAddress (
+                0,
+                DEFAULT_PCI_BUS_NUMBER_PCH,
+                PCI_DEVICE_NUMBER_PCH_LPSS_I2C,
+                (I2cControllerIndex + 1),
+                0
+                );
+
+  I2CBaseAddress = I2CLibPeiMmioRead32 (PciMmBase+R_PCH_LPSS_I2C_BAR);
+
+  //
+  //  Verify the parameters
+  //
+  if (1023 < SlaveAddress ) {
+    Status =  EFI_INVALID_PARAMETER;
+    DEBUG((EFI_D_INFO,"I2cStartRequest Exit with Status %r\r\n", Status));
+    return Status;
+  }
+
+  if(I2CBaseAddress ==  (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE)) {
+    return EFI_SUCCESS;
+  }
+  ProgramPciLpssI2C();
+
+  I2CBaseAddress = (UINT32) (PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE);
+  DEBUG ((EFI_D_ERROR, "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 (I2cControllerIndex);
+  DEBUG((EFI_D_INFO, "I2cDisable Status = %r\r\n", Status));
+
+  I2cBusFrequencySet(I2CBaseAddress, 400 * 1000, &I2cMode);//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(I2cControllerIndex);
+  DEBUG((EFI_D_INFO, "I2cEnable Status = %r\r\n", Status));
+  I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
+  
+  return EFI_SUCCESS;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be read
+  @param  Offset              Offset from which the data has to be read
+  @param  *Byte               Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS        If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
+**/
+EFI_STATUS ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  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 RawIntrStat;
+  UINTN   I2CBaseAddress;
+
+  I2CBaseAddress = (UINT32)(PEI_TEPM_LPSS_I2C0_BAR + I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE);
+
+  Status = EFI_SUCCESS;
+
+  I2CInit(I2cControllerIndex, SlaveAddress);
+
+  ReceiveDataEnd = &ReadBuffer [ReadBytes];
+  if(ReadBytes) {
+    ReceiveRequest = ReadBuffer;
+    DEBUG((EFI_D_INFO,"Read: ---------------%d bytes to RX\r\n",ReceiveDataEnd 
- ReceiveRequest));
+
+    while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadBuffer)) 
{
+      //
+      // Check for NACK
+      //
+      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat );
+      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT )) {
+        I2CLibPeiMmioRead16 ( I2CBaseAddress + R_IC_CLR_TX_ABRT );
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_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;
+        DEBUG((EFI_D_INFO,"MmioRead32 ,1 byte 0x:%x is 
received\r\n",ReceiveData));
+      }
+
+      if(ReceiveDataEnd==ReceiveRequest) {
+        //
+        // Waiting the last request to get data and make (ReceiveDataEnd > 
ReadBuffer) =TRUE.
+        //
+        continue;
+      }
+      
+      //
+      // 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;
+
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  )
+{
+
+  EFI_STATUS Status;
+  UINT32 I2cStatus;
+  UINT8 *TransmitEnd;
+  UINT16 RawIntrStat;
+  UINTN   I2CBaseAddress;
+
+  I2CBaseAddress = (UINT32)PEI_TEPM_LPSS_I2C0_BAR+ I2cControllerIndex * 
PCI_CONFIG_SPACE_SIZE;
+
+  Status = EFI_SUCCESS;
+
+  I2CInit(I2cControllerIndex, SlaveAddress);
+
+  TransmitEnd = &WriteBuffer [WriteBytes];
+  if( WriteBytes ) {
+
+    DEBUG((EFI_D_INFO,"Write: --------------%d bytes to TX\r\n", TransmitEnd - 
WriteBuffer));
+
+    while ( TransmitEnd > WriteBuffer) {
+      I2cStatus = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_STATUS);
+      RawIntrStat = I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_RawIntrStat);
+      if ( 0 != (RawIntrStat & I2C_INTR_TX_ABRT)) {
+        I2CLibPeiMmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT);
+        Status = RETURN_DEVICE_ERROR;
+        DEBUG((EFI_D_ERROR,"TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\r\n", 
TransmitEnd, WriteBuffer));
+        break;
+      }
+      if (0 == ( I2cStatus & STAT_TFNF)) {
+        continue;
+      }
+      if(End && Start) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) 
| B_CMD_RESTART | B_CMD_STOP);
+      } else if (!End && Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) 
| B_CMD_RESTART);
+      } else if (End && !Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, (*WriteBuffer++) 
| B_CMD_STOP);
+      } else if (!End && !Start ) {
+        I2CLibPeiMmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, 
(*WriteBuffer++));
+      }
+      
+      // 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;
+}
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS 
+ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  )
+{
+  EFI_STATUS        Status;
+
+  DEBUG ((EFI_D_ERROR, "ByteReadI2C:---offset:0x%x\n",Offset));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, 
&Offset,TRUE,FALSE);
+  Status = ByteReadI2CBasic(I2cControllerIndex, SlaveAddress, ReadBytes, 
ReadBuffer, TRUE, TRUE);
+
+  return Status;
+}
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  )
+{
+  EFI_STATUS        Status;
+
+  DEBUG ((EFI_D_ERROR, 
"ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer));
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, 1, &Offset, 
TRUE, FALSE);
+  Status = ByteWriteI2CBasic(I2cControllerIndex, SlaveAddress, WriteBytes, 
WriteBuffer, FALSE, TRUE);
+
+  return Status;
+}

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h        
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.h        
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,286 @@
+/** @file
+  I2C PEI Lib Instance.
+
+  Copyright (c) 1999- 2015, 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_PEI_REGS_H
+#define I2C_PEI_REGS_H
+
+#include "PiPei.h"
+
+#define R_PCH_LPC_PMC_BASE                        0x44
+#define B_PCH_LPC_PMC_BASE_BAR                    0xFFFFFE00
+#define R_PCH_PMC_FUNC_DIS                        0x34  // Function Disable 
Register
+#define PCIEX_BASE_ADDRESS                        0xE0000000
+#define PciD31F0RegBase                           PCIEX_BASE_ADDRESS + 
(UINT32) (31 << 15)
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC7             BIT7  // LPSS SPI Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC6             BIT6  // LPSS HSUART #2 
Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC5             BIT5  // LPSS HSUART #1 
Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC4             BIT4  // LPSS I2S Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC3             BIT3  // LPSS PCM Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC2             BIT2  // LPSS I2C #2 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC1             BIT1  // LPSS I2C #1 Disable
+#define B_PCH_PMC_FUNC_DIS_LPSS_FUNC0             BIT0  // LPSS DMA Disable
+
+
+#define DEFAULT_PCI_BUS_NUMBER_PCH       0
+
+#define R_PCH_LPSS_I2C_STSCMD                     0x04  // Status & Command
+#define B_PCH_LPSS_I2C_STSCMD_RMA                 BIT29 // RMA
+#define B_PCH_LPSS_I2C_STSCMD_RCA                 BIT28 // RCA
+#define B_PCH_LPSS_I2C_STSCMD_CAPLIST             BIT20 // Capability List
+#define B_PCH_LPSS_I2C_STSCMD_INTRSTS             BIT19 // Interrupt Status
+#define B_PCH_LPSS_I2C_STSCMD_INTRDIS             BIT10 // Interrupt Disable
+#define B_PCH_LPSS_I2C_STSCMD_SERREN              BIT8  // SERR# Enable
+#define B_PCH_LPSS_I2C_STSCMD_BME                 BIT2  // Bus Master Enable
+#define B_PCH_LPSS_I2C_STSCMD_MSE                 BIT1  // Memory Space Enable
+
+#define R_PCH_LPSS_I2C_BAR                        0x10  // BAR
+#define B_PCH_LPSS_I2C_BAR_BA                     0xFFFFF000 // Base Address
+#define B_PCH_LPSS_I2C_BAR_SI                     0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR_PF                     BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR_TYPE                   (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR_MS                     BIT0  // Message Space
+
+#define R_PCH_LPSS_I2C_BAR1                       0x14  // BAR 1
+#define B_PCH_LPSS_I2C_BAR1_BA                    0xFFFFF000 // Base Address
+#define B_PCH_LPSS_I2C_BAR1_SI                    0x00000FF0 // Size Indicator
+#define B_PCH_LPSS_I2C_BAR1_PF                    BIT3  // Prefetchable
+#define B_PCH_LPSS_I2C_BAR1_TYPE                  (BIT2 | BIT1) // Type
+#define B_PCH_LPSS_I2C_BAR1_MS                    BIT0  // Message Space
+
+#define NUM_RETRIES         0xFFFF
+
+//
+// LPIO I2C Module Memory Space Registers
+//
+#define R_PCH_LPIO_I2C_MEM_RESETS                 0x804 // Software Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_FUNC            BIT1  // Function Clock 
Domain Reset
+#define B_PCH_LPIO_I2C_MEM_RESETS_APB             BIT0  // APB Domain Reset
+
+#define R_PCH_LPSS_I2C_MEM_PCP                    0x800 // Private Clock 
Parameters
+
+#define  bit(a)                   1 << (a)
+
+//
+// MMIO 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_RawIntrStat                ( 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 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
+
+//
+// FIFO write workaround value.
+//
+#define     FIFO_WRITE_DELAY    2
+#define     IC_TAR_10BITADDR_MASTER           BIT12
+#define     FIFO_SIZE                         32
+#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
+
+/**
+  Programe all I2C controllers on LPSS. 
+  
+  I2C0 is function 1 of LPSS. I2C1 is function 2 of LPSS, etc..
+
+  @param   VOID
+
+  @return  EFI_SUCCESS
+**/
+EFI_STATUS
+ProgramPciLpssI2C (
+  VOID
+  );
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be read
+  @param  Offset              Offset from which the data has to be read
+  @param  *Byte               Address to which the value read has to be stored
+  @param  Start               Whether a RESTART is issued before the byte is 
sent or received
+  @param  End                 Whether STOP is generated after a data byte is 
sent or received  
+                                  
+  @return  EFI_SUCCESS        If the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR   Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteReadI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be written
+  @param  Offset               Offset from which the data has to be read
+  @param  *Byte                Address to which the value written is stored
+  @param  Start               Whether a RESTART is issued before the byte is 
sent or received
+  @param  End                 Whether STOP is generated after a data byte is 
sent or received  
+                                  
+  @return  EFI_SUCCESS         IF the byte value has been successfully written
+  @return  EFI_DEVICE_ERROR    Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteWriteI2CBasic(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer,
+  IN  UINT8 Start,
+  IN  UINT8 End
+  );
+
+/**
+  Reads a Byte from I2C Device.
+ 
+  @param  I2cControllerIndex   I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress         Device Address from which the byte value has to 
be read
+  @param  Offset               Offset from which the data has to be read
+  @param  ReadBytes            Number of bytes to be read
+  @param  *ReadBuffer          Address to which the value read has to be stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteReadI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN ReadBytes,
+  OUT UINT8 *ReadBuffer
+  );
+
+/**
+  Writes a Byte to I2C Device.
+ 
+  @param  I2cControllerIndex  I2C Bus no to which the I2C device has been 
connected
+  @param  SlaveAddress        Device Address from which the byte value has to 
be written
+  @param  Offset              Offset from which the data has to be written
+  @param  WriteBytes          Number of bytes to be written
+  @param  *Byte               Address to which the value written is stored
+                                
+  @return  EFI_SUCCESS       IF the byte value has been successfully read
+  @return  EFI_DEVICE_ERROR  Operation Failed, Device Error
+**/
+EFI_STATUS
+ByteWriteI2C(
+  IN  UINT8 I2cControllerIndex,
+  IN  UINT8 SlaveAddress,
+  IN  UINT8 Offset,
+  IN  UINTN WriteBytes,
+  IN  UINT8 *WriteBuffer
+  );
+
+#endif

Added: branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf
===================================================================
--- branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf      
                        (rev 0)
+++ branches/UDK2014.SP1/Vlv2TbltDevicePkg/Library/I2CLibPei/I2CLibPei.inf      
2015-06-02 01:45:22 UTC (rev 17545)
@@ -0,0 +1,45 @@
+## @file
+#  Instance of I2C Library.
+#
+#  Copyright (c) 2010 - 2015, 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                    = PEIM
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = LockBoxLib|PEIM
+  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
+  I2CIoLibPei.c
+
+[LibraryClasses]
+  TimerLib
+
+[PPIs]
+  gEfiPeiStallPpiGuid
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
+
+


------------------------------------------------------------------------------
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to