From nobody Fri Apr 19 10:48:15 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) smtp.mailfrom=edk2-devel-bounces@lists.01.org; dmarc=fail(p=none dis=none) header.from=intel.com Return-Path: Received: from ml01.01.org (ml01.01.org [198.145.21.10]) by mx.zohomail.com with SMTPS id 1532577289307222.1718274736246; Wed, 25 Jul 2018 20:54:49 -0700 (PDT) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id D8FF2210C27B2; Wed, 25 Jul 2018 20:54:48 -0700 (PDT) Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 060EB210C27A8 for ; Wed, 25 Jul 2018 20:54:47 -0700 (PDT) Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by orsmga103.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 25 Jul 2018 20:54:47 -0700 Received: from zwei4-mobl1.ccr.corp.intel.com ([10.239.193.156]) by fmsmga007.fm.intel.com with ESMTP; 25 Jul 2018 20:54:45 -0700 X-Original-To: edk2-devel@lists.01.org Received-SPF: none (zoho.com: 198.145.21.10 is neither permitted nor denied by domain of lists.01.org) client-ip=198.145.21.10; envelope-from=edk2-devel-bounces@lists.01.org; helo=ml01.01.org; Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=134.134.136.65; helo=mga03.intel.com; envelope-from=david.wei@intel.com; receiver=edk2-devel@lists.01.org X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,403,1526367600"; d="scan'208";a="57240453" From: zwei4 To: edk2-devel@lists.01.org Date: Thu, 26 Jul 2018 11:54:40 +0800 Message-Id: <20180726035440.15832-1-david.wei@intel.com> X-Mailer: git-send-email 2.14.1.windows.1 Subject: [edk2] [Patch][edk2-platforms/devel-IntelAtomProcessorE3900] Add I2C Library. X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: David Wei MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: edk2-devel-bounces@lists.01.org Sender: "edk2-devel" X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: David Wei CC: Kelly Steele CC: Mike Wu CC: Mang Guo --- .../SouthCluster/Include/Library/I2CLib.h | 4 +- .../SouthCluster/Include/ScRegs/RegsI2c.h | 31 +- .../SouthCluster/Library/I2CLib/I2CLib.c | 719 +++++++++++++++++= ++++ .../SouthCluster/Library/I2CLib/I2CLib.inf | 50 ++ .../SouthCluster/Library/I2CLibPei/I2CLibPei.c | 6 +- 5 files changed, 802 insertions(+), 8 deletions(-) create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2= CLib/I2CLib.c create mode 100644 Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2= CLib/I2CLib.inf diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I= 2CLib.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CL= ib.h index b897cb9dc4..0c50a3d9a5 100644 --- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/Library/I2CLib.h @@ -1,7 +1,7 @@ /** @file Register Definitions for I2C Library. =20 - Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 1999 - 2018, Intel Corporation. All rights reserved.
=20 This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License @@ -30,7 +30,7 @@ **/ EFI_STATUS ProgramPciLpssI2C ( - VOID + IN UINT8 BusNo ); =20 /** diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/Re= gsI2c.h b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI= 2c.h index 5fc758dd07..8a7463b538 100644 --- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Include/ScRegs/RegsI2c.h @@ -106,10 +106,10 @@ #define R_IC_CLR_START_DET (0x64) ///< Clear START_DET i= nterrupt #define R_IC_CLR_GEN_CALL (0x68) ///< Clear GEN_CALL in= terrupt #define R_IC_ENABLE (0x6C) ///< I2C Enable +#define I2C_ENABLE_ABORT BIT1 +#define I2C_ENABLE_ENABLE BIT0 #define R_IC_STATUS (0x70) ///< I2C Status =20 -#define R_IC_SDA_HOLD (0x7C) ///< I2C IC_DEFAULT_SD= A_HOLD//16bits - #define STAT_MST_ACTIVITY BIT5 ///< Master FSM Activit= y Status. #define STAT_RFF BIT4 ///< RX FIFO is complet= ely full #define STAT_RFNE BIT3 ///< RX FIFO is not emp= ty @@ -118,7 +118,24 @@ =20 #define R_IC_TXFLR (0x74) ///< Transmit FIFO Lev= el Register #define R_IC_RXFLR (0x78) ///< Receive FIFO Leve= l Register +#define R_IC_SDA_HOLD (0x7C) ///< I2C IC_DEFAULT_SD= A_HOLD//16bits #define R_IC_TX_ABRT_SOURCE (0x80) ///< I2C Transmit Abor= t Status Register +#define I2C_ABRT_SLVRD_INTX BIT15 +#define I2C_ABRT_SLV_ARBLOST BIT14 +#define I2C_ABRT_SLVFLUSH_TXFIFO BIT13 +#define I2C_ARB_LOST BIT12 +#define I2C_ABRT_MASTER_DIS BIT11 +#define I2C_ABRT_10B_RD_NORSTRT BIT10 +#define I2C_ABRT_SBYTE_NORSTRT BIT9 +#define I2C_ABRT_HS_NORSTRT BIT8 +#define I2C_ABRT_SBYTE_ACKDET BIT7 +#define I2C_ABRT_HS_ACKDET BIT6 +#define I2C_ABRT_GCALL_READ BIT5 +#define I2C_ABRT_GCALL_NOACK BIT4 +#define I2C_ABRT_TXDATA_NOACK BIT3 +#define I2C_ABRT_10ADDR2_NOACK BIT2 +#define I2C_ABRT_10ADDR1_NOACK BIT1 +#define I2C_ABRT_7B_ADDR_NOACK BIT0 #define R_IC_SLV_DATA_NACK_ONLY (0x84) ///< Generate SLV_DATA= _NACK Register #define R_IC_DMA_CR (0x88) ///< DMA Control Regis= ter #define R_IC_DMA_TDLR (0x8C) ///< DMA Transmit Data= Level @@ -130,7 +147,15 @@ #define R_IC_COMP_VERSION (0xF8) ///< Component Version= ID #define R_IC_COMP_TYPE (0xFC) ///< Component Type =20 -#define R_IC_CLK_GATE (0xC0) ///< Clock Gate +#define R_IC_RESET_CONTROL (0x204) ///< Reset control +#define I2C_RESET_CONTROLLER (BIT0 | BIT1) +#define I2C_RESET_IDMA (BIT2) + +#define R_IC_CLK_GATE (0x238) ///< Clock Gate +#define I2C_FORCE_CLOCK_ON (BIT0 | BIT1) +#define I2C_FORCE_CLOCK_OFF (BIT1) +#define I2C_FORCE_IDMA_CLOCK_ON (BIT2 | BIT3) +#define I2C_FORCE_IDMA_CLOCK_OFF (BIT3) =20 #define I2C_SS_SCL_HCNT_VALUE_100M 0x1DD #define I2C_SS_SCL_LCNT_VALUE_100M 0x1E4 diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2= CLib.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib= .c new file mode 100644 index 0000000000..f205a6ce44 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.c @@ -0,0 +1,719 @@ +/** @file + Dxe library for I2C bus driver. + +@copyright + Copyright (c) 1999 - 2018 Intel Corporation. All rights reserved + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BS= D License + which accompanies this distribution. The full text of the license may b= e 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 IMP= LIED. +**/ + +#include +#include +#include +#include +#include +#include +#include + +#pragma pack(push, 1) +typedef struct _LPSS_PCI_DEVICE_INFO { + UINTN Segment; + UINTN BusNum; + UINTN DeviceNum; + UINTN FunctionNum; + UINTN Bar0; + UINTN Bar1; +} LPSS_PCI_DEVICE_INFO; + +typedef enum { + Standard_Speed =3D 1, + Fast_Speed =3D 2, + High_Speed =3D 3, +} I2C_SPEED; + +typedef struct _LPSS_I2C_CLOCK_SCL_INFO { + UINT8 I2c_Speed; + UINT16 SS_SCL_HCNT; + UINT16 SS_SCL_LCNT; + UINT16 FS_SCL_HCNT; + UINT16 FS_SCL_LCNT; + UINT16 HS_SCL_HCNT; + UINT16 HS_SCL_LCNT; +} LPSS_I2C_CLOCK_SCL_INFO; +#pragma pack(pop) + +LPSS_PCI_DEVICE_INFO mLpssPciDeviceList[] =3D { + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTI= ON_NUMBER_LPSS_I2C0, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*0) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTI= ON_NUMBER_LPSS_I2C1, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*1) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTI= ON_NUMBER_LPSS_I2C2, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*2) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C0, PCI_FUNCTI= ON_NUMBER_LPSS_I2C3, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*3) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTI= ON_NUMBER_LPSS_I2C4, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*4) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTI= ON_NUMBER_LPSS_I2C5, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*5) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTI= ON_NUMBER_LPSS_I2C6, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*6) + LPSS_I2C_TMP_BAR1_OFFSET}, + {0, DEFAULT_PCI_BUS_NUMBER_SC, PCI_DEVICE_NUMBER_LPSS_I2C1, PCI_FUNCTI= ON_NUMBER_LPSS_I2C7, LPSS_I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7), LPSS= _I2C0_TMP_BAR0 + (LPSS_I2C_TMP_BAR0_DELTA*7) + LPSS_I2C_TMP_BAR1_OFFSET}, +}; + +#define LPSS_PCI_DEVICE_NUMBER sizeof(mLpssPciDeviceList)/sizeof(LPSS_PCI= _DEVICE_INFO) + +LPSS_I2C_CLOCK_SCL_INFO mLPSS_I2C_CLOCK_SCL_INFO[] =3D { + {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13}, + {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13}, + {Fast_Speed, 0x244, 0x2D0, 0x64, 0xC8, 0x06, 0x13}, + {High_Speed, 0x244, 0x2DA, 0x1E, 0x3C, 0x06, 0x13}, + {High_Speed, 0x244, 0x2DA, 0x1E, 0x50, 0x06, 0x13}, + {Fast_Speed, 0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13}, + {Fast_Speed, 0x244, 0x2D0, 0x69, 0xC8, 0x06, 0x13}, + {Fast_Speed, 0x244, 0x2D0, 0x70, 0xC8, 0x06, 0x13}, +}; + +#define LPSS_I2C_CLOCK_SCL_INFO_NUMBER sizeof(mLPSS_I2C_CLOCK_SCL_INFO)/s= izeof(LPSS_I2C_CLOCK_SCL_INFO) + + +/** + Program LPSS I2C PCI controller's BAR0 and enable memory decode. + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + + @retval EFI_SUCCESS - I2C controller's BAR0 is programmed and = memory decode enabled. + @retval EFI_NOT_READY - I2C controller's is not exist or its fun= ction has been disabled. +**/ +EFI_STATUS +ProgramPciLpssI2C ( + IN UINT8 BusNo + ) +{ + UINTN PciMmBase=3D0; + UINT32 I2CBar0; + UINT32 I2CBar1; + UINT32 PmcBase; + UINT32 D32; + UINT32 I2cPortDisable[] =3D { + B_PMC_FUNC_DIS_LPSS_I2C0, + B_PMC_FUNC_DIS_LPSS_I2C1, + B_PMC_FUNC_DIS_LPSS_I2C2, + B_PMC_FUNC_DIS_LPSS_I2C3, + B_PMC_FUNC_DIS_LPSS_I2C4, + B_PMC_FUNC_DIS_LPSS_I2C5, + B_PMC_FUNC_DIS_LPSS_I2C6, + B_PMC_FUNC_DIS_LPSS_I2C7 + }; + + DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() Start\n")); + + // + // Check PMC disable register + // + PmcBase =3D PMC_BASE_ADDRESS; + D32 =3D MmioRead32 (PmcBase + R_PMC_FUNC_DIS); + + if (D32 =3D=3D 0xFFFFFFFF) { + DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() PMC disable register not avai= lable. [%08x]\n", PMC_BASE_ADDRESS)); + } else { + if ((D32 & I2cPortDisable[BusNo]) !=3D 0) { + // This I2C port is disabled. Turn it on. + D32 &=3D ~I2cPortDisable[BusNo]; + MmioWrite32 (PmcBase + R_PMC_FUNC_DIS, D32); + DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() enable I2C controller #%x\n= ", BusNo)); + // Make sure it took. + if (D32 !=3D MmioRead32 (PmcBase + R_PMC_FUNC_DIS)) { + DEBUG ((DEBUG_ERROR, "ProgramPciLpssI2C() failed to enable I2C con= troller #%x [%08x:%08x]\n", BusNo, D32, MmioRead32 (PmcBase + R_PMC_FUNC_DI= S))); + return EFI_DEVICE_ERROR; + } + } + } + + DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C()------------BusNo=3D%x\n", BusNo= )); + + PciMmBase =3D MmPciAddress ( + mLpssPciDeviceList[BusNo].Segment, + mLpssPciDeviceList[BusNo].BusNum, + mLpssPciDeviceList[BusNo].DeviceNum, + mLpssPciDeviceList[BusNo].FunctionNum, + 0 + ); + DEBUG ((DEBUG_INFO, "Program Pci Lpss I2C Device %x %x %x PciMmBase:%x\= n", \ + mLpssPciDeviceList[BusNo].BusNum, \ + mLpssPciDeviceList[BusNo].DeviceNum, \ + mLpssPciDeviceList[BusNo].FunctionNum, PciMmBase)); + + // + // Check if device present + // + if (MmioRead32 (PciMmBase) !=3D 0xFFFFFFFF) { + if ((MmioRead32 (PciMmBase + R_LPSS_IO_STSCMD) & B_LPSS_IO_STSCMD_MSE)= ) { + // + // In Pei stage, we always disable Bus master, and memory space enab= ling for BAR re-programming + // In DXE stage, will read existing BAR value instead of re-programm= ing + // + I2CBar0 =3D MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_B= A; + I2CBar1 =3D MmioRead32 (PciMmBase + R_LPSS_IO_BAR1) & B_LPSS_IO_BAR_= BA; + if ((I2CBar0 !=3D (UINT32)mLpssPciDeviceList[BusNo].Bar0) || (I2CBar= 1 !=3D (UINT32)mLpssPciDeviceList[BusNo].Bar1)) { + mLpssPciDeviceList[BusNo].Bar0 =3D MmioRead32 (PciMmBase + R_LPSS_= IO_BAR) & B_LPSS_IO_BAR_BA; // get the address allocated. + mLpssPciDeviceList[BusNo].Bar1 =3D MmioRead32 (PciMmBase + R_LPSS_= IO_BAR1) & B_LPSS_IO_BAR_BA; + DEBUG ((DEBUG_INFO, "Get bar0:0x%x bar1:0x%x\n", mLpssPciDeviceLis= t[BusNo].Bar0, mLpssPciDeviceList[BusNo].Bar1)); + } + } else { + // + // Program BAR 0 + // + ASSERT (((mLpssPciDeviceList[BusNo].Bar0 & B_LPSS_IO_BAR_BA) =3D=3D = mLpssPciDeviceList[BusNo].Bar0) && (mLpssPciDeviceList[BusNo].Bar0 !=3D 0)); + MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR), (UINT32) (mLpssPci= DeviceList[BusNo].Bar0 & B_LPSS_IO_BAR_BA)); + // + // Program BAR 1 + // + ASSERT (((mLpssPciDeviceList[BusNo].Bar1 & B_LPSS_IO_BAR1_BA) =3D=3D= mLpssPciDeviceList[BusNo].Bar1) && (mLpssPciDeviceList[BusNo].Bar1 !=3D 0)= ); + MmioWrite32 ((UINTN) (PciMmBase + R_LPSS_IO_BAR1), (UINT32) (mLpssPc= iDeviceList[BusNo].Bar1 & B_LPSS_IO_BAR1_BA)); + // + // Bus Master Enable & Memory Space Enable + // + MmioOr32 ((UINTN) (PciMmBase + R_LPSS_IO_STSCMD), (UINT32) (B_LPSS_I= O_STSCMD_BME | B_LPSS_IO_STSCMD_MSE)); + ASSERT (MmioRead32 (mLpssPciDeviceList[BusNo].Bar0) !=3D 0xFFFFFFFF); + } + + // + // Release Resets + // + MmioWrite32 (mLpssPciDeviceList[BusNo].Bar0 + R_LPSS_IO_MEM_RESETS, B_= LPSS_IO_MEM_HC_RESET_REL | B_LPSS_IO_MEM_iDMA_RESET_REL); + + DEBUG ((DEBUG_INFO, "ProgramPciLpssI2C() Programmed()\n")); + return EFI_SUCCESS; + } else { + DEBUG ((DEBUG_ERROR, "Pci Lpss I2C Device %x %x %x is not existing!\= n", + mLpssPciDeviceList[BusNo].BusNum, + mLpssPciDeviceList[BusNo].DeviceNum, + mLpssPciDeviceList[BusNo].FunctionNum)); + + return EFI_NOT_READY; + } +} + +/** + Disable I2C host controller + + @param[in] I2CBaseAddress - BAR0 address of I2C host controller + + @retval EFI_SUCCESS - I2C host controller is completely inacti= ve. + @retval EFI_NOT_READY - I2C host controller is still in an enabl= ed state. +**/ +EFI_STATUS +I2cDisable ( + IN UINTN I2CBaseAddress + ) +{ + UINT32 NumTries =3D 10000; // 0.1 seconds + + MmioWrite32 (I2CBaseAddress + R_IC_ENABLE, 0); + while (0 !=3D ( MmioRead32 ( I2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) { + MicroSecondDelay (10); + NumTries --; + if (0 =3D=3D NumTries) return EFI_NOT_READY; + } + return EFI_SUCCESS; +} + +/** + Enable I2C host controller + + @param[in] I2CBaseAddress - BAR0 address of I2C host controller + + @retval EFI_SUCCESS - I2C host controller is in an enabled sta= te. + @retval EFI_NOT_READY - I2C host controller is still inactive. +**/ +EFI_STATUS +I2cEnable ( + IN UINTN I2CBaseAddress + ) +{ + UINT32 NumTries =3D 10000; // 0.1 seconds + + MmioWrite32 (I2CBaseAddress + R_IC_ENABLE, 1); + while (0 =3D=3D (MmioRead32 (I2CBaseAddress + R_IC_ENABLE_STATUS) & 1)) { + MicroSecondDelay (10); + NumTries --; + if (0 =3D=3D NumTries) return EFI_NOT_READY; + } + return EFI_SUCCESS; +} + +/** + Set the I2C controller bus clock frequency. + + The software and controller do a best case effort of using the specified + frequency for the I2C bus. If the frequency does not match exactly then + the controller will use a slightly lower frequency for the I2C to avoid + exceeding the operating conditions for any of the I2C devices on the bus. + For example if 400 KHz was specified and the controller's divide network + only supports 402 KHz or 398 KHz then the controller would be set to 398 + KHz. However if the desired frequency is 400 KHz and the controller only + supports 1 MHz and 100 KHz then this routine would return EFI_UNSUPPORTE= D. + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + @param[in] I2CBaseAddress - BAR0 address of I2C host controller + @param[out] I2cMode - I2C operation mode. + Standard Speed: 100 KHz + Fast Speed : 400 KHz + High Speed : 3.4 MHz + + @retval EFI_SUCCESS - The bus frequency was set successfully. +**/ +EFI_STATUS +I2cBusFrequencySet ( + IN UINT8 BusNo, + IN UINTN I2CBaseAddress, + OUT UINT16 *I2cMode + ) +{ + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet bus: %d\r\n", BusNo)); + ASSERT ((BusNo < LPSS_I2C_CLOCK_SCL_INFO_NUMBER)); + // + // Set the 100 KHz clock divider according to SV result and I2C spec + // + MmioWrite32 (I2CBaseAddress + R_IC_SS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].SS_SCL_HCNT); + MmioWrite32 (I2CBaseAddress + R_IC_SS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].SS_SCL_LCNT); + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_SS_SCL_HCNT: 0x%08X, R_IC_S= S_SCL_LCNT: 0x%08X\r\n",\ + MmioRead32 (I2CBaseAddress + R_IC_SS_SCL_HCNT), MmioRead32 (I2CBa= seAddress + R_IC_SS_SCL_LCNT))); + // + // Set the 400 KHz clock divider according to SV result and I2C spec + // + MmioWrite32 (I2CBaseAddress + R_IC_FS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].FS_SCL_HCNT); + MmioWrite32 (I2CBaseAddress + R_IC_FS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].FS_SCL_LCNT); + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_FS_SCL_HCNT: 0x%08X, R_IC_F= S_SCL_LCNT: 0x%08X\r\n",\ + MmioRead32 (I2CBaseAddress + R_IC_FS_SCL_HCNT), MmioRead32 (I2CBa= seAddress + R_IC_FS_SCL_LCNT))); + // + // Set the 3.4MHz clock divider according to SV result and I2C spec + // + MmioWrite32 (I2CBaseAddress + R_IC_HS_SCL_HCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].HS_SCL_HCNT); + MmioWrite32 (I2CBaseAddress + R_IC_HS_SCL_LCNT, (UINT16)mLPSS_I2C_CLOCK_= SCL_INFO[BusNo].HS_SCL_LCNT); + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_HS_SCL_HCNT: 0x%08X, R_IC_H= S_SCL_LCNT: 0x%08X\r\n",\ + MmioRead32 (I2CBaseAddress + R_IC_HS_SCL_HCNT), MmioRead32 (I2CBa= seAddress + R_IC_HS_SCL_LCNT))); + + switch (mLPSS_I2C_CLOCK_SCL_INFO[BusNo].I2c_Speed) { + case Standard_Speed: + MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //100K + *I2cMode =3D V_SPEED_STANDARD; + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMo= de)); + break; + + case Fast_Speed: + MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //400K + *I2cMode =3D V_SPEED_FAST; + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMo= de)); + break; + + case High_Speed: + MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //3.4M + *I2cMode =3D V_SPEED_HIGH; + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMo= de)); + break; + + default: + MmioWrite32 ( I2CBaseAddress + R_IC_SDA_HOLD, (UINT16)0x06); //400K + *I2cMode =3D V_SPEED_FAST; + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMo= de)); + } + + // + // Select the frequency counter + // Enable restart condition, + // Enable master FSM, disable slave FSM + // + *I2cMode |=3D B_IC_RESTART_EN | B_IC_SLAVE_DISABLE | B_MASTER_MODE; + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet R_IC_SDA_HOLD: 0x%08X\r\n", Mmio= Read32 (I2CBaseAddress + R_IC_SDA_HOLD))); + DEBUG ((DEBUG_INFO, "I2cBusFrequencySet I2cMode: 0x%04X\r\n", *I2cMode)); + + return EFI_SUCCESS; +} + +/** + Initializes the host controller to execute I2C commands. + + @param[in] BusNo - I2C Bus number to which the I2C device= has been connected + @param[in] SlaveAddress - Slave address of the I2C device + @param[out] I2CBaseAddress - Return BAR0 address of I2C host contro= ller + + @retval EFI_SUCCESS - Initialization on the I2C host control= ler completed. + @retval EFI_INVALID_PARAMETER - Invalid slave address + @retval EFI_DEVICE_ERROR - Operation failed, device error + @retval Others - Failed to initialize I2C host controll= er +**/ +EFI_STATUS +I2CInit ( + IN UINT8 BusNo, + IN UINT16 SlaveAddress, + OUT UINTN *I2CBaseAddress + ) +{ + EFI_STATUS Status; + UINT32 NumTries; + UINT16 I2cMode; + UINTN PciMmBase; + UINTN BaseAddress; + + // + // Verify the parameters + // + if (1023 < SlaveAddress) { + Status =3D EFI_INVALID_PARAMETER; + DEBUG ((DEBUG_INFO, "I2cStartRequest Exit with Status %r\r\n", Status)= ); + return Status; + } + + PciMmBase =3D MmPciAddress ( + mLpssPciDeviceList[BusNo].Segment, + mLpssPciDeviceList[BusNo].BusNum, + mLpssPciDeviceList[BusNo].DeviceNum, + mLpssPciDeviceList[BusNo].FunctionNum, + 0 + ); + + BaseAddress =3D MmioRead32 (PciMmBase + R_LPSS_IO_BAR) & B_LPSS_IO_BAR_B= A; + + // + // Skip reinit if targeting the same I2C bus + // + if (BaseAddress =3D=3D mLpssPciDeviceList[BusNo].Bar0) { + MmioWrite32 (BaseAddress + R_IC_TAR, SlaveAddress); + *I2CBaseAddress =3D BaseAddress; + return EFI_SUCCESS; + } + + Status =3D ProgramPciLpssI2C (BusNo); + if (Status !=3D EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "ProgramPciLpssI2C failed ! %r\r\n", Status)); + return Status; + } + + BaseAddress =3D (UINT32) mLpssPciDeviceList[BusNo].Bar0; + DEBUG ((DEBUG_INFO, "I2CBaseAddress =3D 0x%x \n", BaseAddress)); + + NumTries =3D 10000; // 1 seconds + while ((STAT_MST_ACTIVITY =3D=3D (MmioRead32 (BaseAddress + R_IC_STATUS)= & STAT_MST_ACTIVITY))) { + MicroSecondDelay (10); + NumTries --; + if (0 =3D=3D NumTries) { + DEBUG ((DEBUG_ERROR, "Try timeout\r\n")); + return EFI_DEVICE_ERROR; + } + } + + Status =3D I2cDisable(BaseAddress); + DEBUG ((DEBUG_INFO, "I2cDisable Status =3D %r\r\n", Status)); + I2cBusFrequencySet(BusNo, BaseAddress, &I2cMode); // Set I2cMode + + MmioWrite32 (BaseAddress + R_IC_INTR_MASK, 0x0); + if (0x7f < SlaveAddress) { + SlaveAddress =3D (SlaveAddress & 0x3ff) | IC_TAR_10BITADDR_MASTER; + } + MmioWrite32 (BaseAddress + R_IC_TAR, SlaveAddress); + MmioWrite32 (BaseAddress + R_IC_RX_TL, 0); + MmioWrite32 (BaseAddress + R_IC_TX_TL, 0); + MmioWrite32 (BaseAddress + R_IC_CON, I2cMode); + Status =3D I2cEnable(BaseAddress); + + DEBUG((DEBUG_INFO, "I2cEnable Status =3D %r\r\n", Status)); + MmioRead32 (BaseAddress + R_IC_CLR_TX_ABRT); + *I2CBaseAddress =3D BaseAddress; + return EFI_SUCCESS; +} + +/** + Read bytes from I2C Device + This is actual I2C hardware operation function. + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + @param[in] SlaveAddress - Slave address of the I2C device (7-bit) + @param[in] ReadBytes - Number of bytes to be read + @param[out] ReadBuffer - Address to which the value read has to b= e stored + @param[in] Start - It controls whether a RESTART is issued = before the byte is sent or received. + @param[in] End - It controls whether a STOP is issued aft= er the byte is sent or received. + + @retval EFI_SUCCESS - The byte value read successfully + @retval EFI_DEVICE_ERROR - Operation failed + @retval EFI_TIMEOUT - Hardware retry timeout + @retval Others - Failed to read a byte via I2C +**/ +EFI_STATUS +ByteReadI2C_Basic ( + IN UINT8 BusNo, + IN UINT8 SlaveAddress, + IN UINTN ReadBytes, + OUT UINT8 *ReadBuffer, + IN UINT8 Start, + IN UINT8 End + ) +{ + EFI_STATUS Status; + UINT32 I2cStatus; + UINT16 ReceiveData; + UINT8 *ReceiveDataEnd; + UINT8 *ReceiveRequest; + UINT16 raw_intr_stat; + UINT32 Count =3D 0; + UINTN I2CBaseAddress; + UINT8 *ReadPtr; + + // + // Read should always after write, so, base address should already be in= itialized, then get base address directly + // + I2CBaseAddress =3D (UINT32) mLpssPciDeviceList[BusNo].Bar0; + DEBUG ((DEBUG_INFO, "mLpssPciDeviceList returned base address =3D 0x%08x= \n", I2CBaseAddress)); + + Status =3D EFI_SUCCESS; + + ReceiveDataEnd =3D &ReadBuffer [ReadBytes]; + ReadPtr =3D ReadBuffer; + if (ReadBytes) { + ReceiveRequest =3D ReadBuffer; + //DEBUG((DEBUG_INFO,"Read: ---------------%d bytes to RX\r\n", Receive= DataEnd - ReceiveRequest)); + + while ((ReceiveDataEnd > ReceiveRequest) || (ReceiveDataEnd > ReadPtr)= ) { + // + // Check for NACK + // + raw_intr_stat =3D (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR= _STAT); + if (0 !=3D (raw_intr_stat & I2C_INTR_TX_ABRT)) { + MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT); + Status =3D EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "TX ABRT ,%d bytes hasn't been transferred\r\= n", ReceiveDataEnd - ReceiveRequest)); + break; + } + =20 + // + // Determine if another byte was received + // + I2cStatus =3D (UINT16)MmioRead32 (I2CBaseAddress + R_IC_STATUS); + if (0 !=3D (I2cStatus & STAT_RFNE)) { + ReceiveData =3D (UINT16)MmioRead32 (I2CBaseAddress + R_IC_DATA_CMD= ); + *ReadPtr++ =3D (UINT8)ReceiveData; + DEBUG ((DEBUG_INFO, "MmioRead32 ,1 byte 0x:%x is received\r\n", Re= ceiveData)); + } + + if (ReceiveDataEnd =3D=3D ReceiveRequest) { + MicroSecondDelay (FIFO_WRITE_DELAY); + Count++; + if (Count < 1024) { // sys hung avoid no ul-pmc device + continue; // Waiting the last request to get data and make (Rece= iveDataEnd > ReadBuffer) =3DTRUE. + } else { + break; + } + } + // + // Wait until a read request will fit + // + if (0 =3D=3D (I2cStatus & STAT_TFNF)) { + MicroSecondDelay (10); + continue; + } + // + // Issue the next read request + // + if (End && Start) { + MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_REST= ART|B_CMD_STOP); + } else if (!End && Start) { + MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_REST= ART); + } else if (End && !Start) { + MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD|B_CMD_STOP= ); + } else if (!End && !Start) { + MmioWrite32 (I2CBaseAddress + R_IC_DATA_CMD, B_READ_CMD); + } + MicroSecondDelay (FIFO_WRITE_DELAY); //wait after send cmd + + ReceiveRequest +=3D 1; + } + } + return Status; + +} + +/** + Write bytes to I2C Device + This is actual I2C hardware operation function. + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + @param[in] SlaveAddress - Slave address of the I2C device (7-bit) + @param[in] WriteBytes - Number of bytes to be written + @param[in] WriteBuffer - Address to which the byte value has to b= e written + @param[in] Start - It controls whether a RESTART is issued = before the byte is sent or received. + @param[in] End - It controls whether a STOP is issued aft= er the byte is sent or received. + + @retval EFI_SUCCESS - The byte value written successfully + @retval EFI_DEVICE_ERROR - Operation failed + @retval EFI_TIMEOUT - Hardware retry timeout + @retval Others - Failed to write a byte via I2C +**/ +EFI_STATUS +ByteWriteI2C_Basic ( + IN UINT8 BusNo, + IN UINT8 SlaveAddress, + IN UINTN WriteBytes, + IN UINT8 *WriteBuffer, + IN UINT8 Start, + IN UINT8 End + ) +{ + UINT16 Data16; + EFI_STATUS Status; + UINT32 I2cStatus; + UINT8 *TransmitPtr; + UINT8 *TransmitEnd; + UINT16 raw_intr_stat; + UINT32 Count=3D0; + UINTN I2CBaseAddress; + + Status =3D I2CInit (BusNo, SlaveAddress, &I2CBaseAddress); + if (Status !=3D EFI_SUCCESS) { + DEBUG ((DEBUG_ERROR, "I2CInit failed ! %r\r\n", Status)); + return Status; + } + DEBUG ((DEBUG_INFO, "I2CInit returned base address =3D 0x%08x\n", I2CBas= eAddress)); + =20 + TransmitPtr =3D WriteBuffer; + TransmitEnd =3D &WriteBuffer [WriteBytes]; + if (WriteBytes) { + raw_intr_stat =3D (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR_S= TAT); + if (0 !=3D (raw_intr_stat & I2C_INTR_TX_ABRT)) { + MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT); + DEBUG ((DEBUG_ERROR, "%a(#%d) - raw_intr_stat =3D %04x\n", __FUNCTIO= N__, __LINE__, TransmitEnd, TransmitPtr, raw_intr_stat)); + } + + //DEBUG ((DEBUG_INFO, "Write: --------------%d bytes to TX\r\n", Trans= mitEnd - WriteBuffer)); + while (TransmitEnd > TransmitPtr) { + I2cStatus =3D MmioRead32 (I2CBaseAddress + R_IC_STATUS); + raw_intr_stat =3D (UINT16)MmioRead32 (I2CBaseAddress + R_IC_RAW_INTR= _STAT); + if (0 !=3D (raw_intr_stat & I2C_INTR_TX_ABRT)) { + MmioRead32 (I2CBaseAddress + R_IC_CLR_TX_ABRT); + Status =3D EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "%a(#%d) - TX ABRT TransmitEnd:0x%x WritePtr:= 0x%x\r\n", __FUNCTION__, __LINE__, TransmitEnd, TransmitPtr)); + break; + } + if (0 =3D=3D (I2cStatus & STAT_TFNF)) { + MicroSecondDelay (FIFO_WRITE_DELAY); + continue; + } + + Data16 =3D (UINT16) *TransmitPtr; + if (End && Start) { + Data16 |=3D (B_CMD_RESTART | B_CMD_STOP); + } else if (!End && Start) { + Data16 |=3D B_CMD_RESTART; + } else if (End && !Start) { + Data16 |=3D B_CMD_STOP; + } + Data16 =3D MmioWrite16 (I2CBaseAddress + R_IC_DATA_CMD, Data16); + TransmitPtr++; + + // + // Add a small delay to work around some odd behavior being seen. W= ithout this delay bytes get dropped. + // + MicroSecondDelay (FIFO_WRITE_DELAY); + // + // Time out + // + while (1) { + raw_intr_stat =3D MmioRead16 (I2CBaseAddress + R_IC_RAW_INTR_STAT); + if (0 !=3D ( raw_intr_stat & I2C_INTR_TX_ABRT)) { + MmioRead16 (I2CBaseAddress + R_IC_CLR_TX_ABRT); + Status =3D EFI_DEVICE_ERROR; + DEBUG ((DEBUG_ERROR, "TX ABRT TransmitEnd:0x%x WriteBuffer:0x%x\= r\n", TransmitEnd, WriteBuffer)); + } + if (0 =3D=3D MmioRead16(I2CBaseAddress + R_IC_TXFLR)) break; + + MicroSecondDelay (FIFO_WRITE_DELAY); + Count++; + if (Count < 1024) { //to avoid sys hung without ul-pmc device on R= VP + continue; //Waiting the last request to get data and make (Recei= veDataEnd > ReadBuffer) =3DTRUE. + } else { + DEBUG ((DEBUG_ERROR, "hardware timeout, 1024 times try!\r\n")); + Status =3D EFI_TIMEOUT; + break; + } + }//while( 1 ) + + } + + } + if (EFI_ERROR (Status)) + DEBUG ((DEBUG_ERROR, "I2cStartRequest Exit with Status %r\r\n", Status= )); + + return Status; +} + +/** + Read bytes from I2C Device + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + @param[in] SlaveAddress - Slave address of the I2C device (7-bit) + @param[in] Offset - Register offset from which the data has = to be read + @param[in] ReadBytes - Number of bytes to be read + @param[out] ReadBuffer - Address to which the value read has to b= e stored + + @retval EFI_SUCCESS - Read bytes from I2C device successfully + @retval Others - Return status depends on ByteReadI2C_Bas= ic +**/ +EFI_STATUS +ByteReadI2C ( + IN UINT8 BusNo, + IN UINT8 SlaveAddress, + IN UINT8 Offset, + IN UINTN ReadBytes, + OUT UINT8 *ReadBuffer + ) +{ + EFI_STATUS Status; + + //DEBUG ((EFI_D_INFO, "ByteReadI2C:---offset:0x%x\n",Offset)); + Status =3D ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FA= LSE); + if (!EFI_ERROR (Status)) { + Status =3D ByteReadI2C_Basic (BusNo, SlaveAddress, ReadBytes, ReadBuff= er, TRUE, TRUE); + } else { + DEBUG ((DEBUG_ERROR, "ByteReadI2C/ByteWriteI2C_Basic: %r\n", Status)); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ByteReadI2C: %r\n", Status)); + } + + return Status; +} + +/** + Write bytes to I2C Device + + @param[in] BusNo - I2C Bus number to which the I2C device h= as been connected + @param[in] SlaveAddress - Slave address of the I2C device (7-bit) + @param[in] Offset - Register offset from which the data has = to be read + @param[in] WriteBytes - Number of bytes to be written + @param[in] WriteBuffer - Address to which the byte value has to b= e written + + @retval EFI_SUCCESS - Write bytes to I2C device successfully + @retval Others - Return status depends on ByteWriteI2C_Ba= sic +**/ +EFI_STATUS +ByteWriteI2C ( + IN UINT8 BusNo, + IN UINT8 SlaveAddress, + IN UINT8 Offset, + IN UINTN WriteBytes, + IN UINT8 *WriteBuffer + ) +{ + EFI_STATUS Status; + + //DEBUG ((EFI_D_INFO, "ByteWriteI2C:---offset/bytes/buf:0x%x,0x%x,0x%x,0= x%x\n",Offset,WriteBytes,WriteBuffer,*WriteBuffer)); + Status =3D ByteWriteI2C_Basic (BusNo, SlaveAddress, 1, &Offset, TRUE, FA= LSE); + if (!EFI_ERROR (Status)) { + Status =3D ByteWriteI2C_Basic (BusNo, SlaveAddress, WriteBytes, WriteB= uffer, FALSE, TRUE); + } else { + DEBUG ((DEBUG_ERROR, "ByteWriteI2C/ByteWriteI2C_Basic: %r\n", Status)); + } + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "ByteWriteI2C: %r\n", Status)); + } + + return Status; +} diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2= CLib.inf b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CL= ib.inf new file mode 100644 index 0000000000..81fe55a400 --- /dev/null +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLib/I2CLib.inf @@ -0,0 +1,50 @@ +### @file +# Dxe library for I2C bus driver. +# +#@copyright +# Copyright (c) 2010 - 2018 Intel Corporation. All rights reserved +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the B= SD 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 IM= PLIED. +### + +[Defines] + INF_VERSION =3D 0x00010005 + BASE_NAME =3D I2CLib + FILE_GUID =3D 7f62bf44-2ba7-4c2d-9d4a-91c8906ff053 + MODULE_TYPE =3D BASE + VERSION_STRING =3D 1.0 + LIBRARY_CLASS =3D I2CLib +# CONSTRUCTOR =3D IntelI2CLibConstructor + +# +# The following information is for reference only and not required by the = build tools. +# +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC +# + +[Sources.common] + I2CLib.c + +[LibraryClasses] + BaseLib + IoLib + TimerLib + +[Packages] + MdePkg/MdePkg.dec + BroxtonSiPkg/BroxtonSiPkg.dec + +[Protocols] + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## SOMETIMES_CONSUMES + gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress ## SOMETIMES_CONSUMES + + + diff --git a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei= /I2CLibPei.c b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibP= ei/I2CLibPei.c index d15170a35c..ad154d57e0 100644 --- a/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLib= Pei.c +++ b/Silicon/BroxtonSoC/BroxtonSiPkg/SouthCluster/Library/I2CLibPei/I2CLib= Pei.c @@ -1,7 +1,7 @@ /** @file Pei library for I2C bus driver. =20 - Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.
+ Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.
=20 This program and the accompanying materials are licensed and made available under the terms and conditions of the BS= D License @@ -114,7 +114,7 @@ IntelI2CPeiLibConstructor ( **/ EFI_STATUS ProgramPciLpssI2C ( - VOID + IN UINT8 BusNo ) { UINT32 PmcBase; @@ -387,7 +387,7 @@ I2CInit ( // // Need to enable the I2C PCI device // - ProgramPciLpssI2C (); + ProgramPciLpssI2C (BusNo); =20 I2CBaseAddress =3D (UINT32) (LPSS_I2C0_TMP_BAR0 + (BusNo * LPSS_I2C_TM= P_BAR0_DELTA)); if (DebugFlag) DEBUG ((DEBUG_INFO, "I2CBaseAddress =3D 0x%x \n", I2CBa= seAddress)); --=20 2.14.1.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel