From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mga11.intel.com (mga11.intel.com []) by mx.groups.io with SMTP id smtpd.web08.27712.1612143430402429223 for ; Sun, 31 Jan 2021 17:37:37 -0800 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: heng.luo@intel.com) IronPort-SDR: aWijQkT+QQVMLLtja4PxcknKgz6vruwhdKQj0AkpGnak54SFiKZ070Bm4hllP2ttOF8KtpFNm5 BdpMo9ZLjNfQ== X-IronPort-AV: E=McAfee;i="6000,8403,9881"; a="177113944" X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="177113944" Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 31 Jan 2021 17:37:29 -0800 IronPort-SDR: WD8fIi99scLKsn0x7ljviVLmJrWU1rzbjFzKUJv7ajRnQqlBcMTXHjAB2b/Cxaq/rotTiWVBm9 ZSi/y6S2BJYg== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,391,1602572400"; d="scan'208";a="368718656" Received: from hengluo-dev.ccr.corp.intel.com ([10.239.153.154]) by fmsmga008.fm.intel.com with ESMTP; 31 Jan 2021 17:37:27 -0800 From: "Heng Luo" To: devel@edk2.groups.io Cc: Sai Chaganty , Nate DeSimone Subject: [PATCH 17/40] TigerlakeSiliconPkg/IpBlock: Add Gpio component Date: Mon, 1 Feb 2021 09:36:34 +0800 Message-Id: <20210201013657.1833-17-heng.luo@intel.com> X-Mailer: git-send-email 2.24.0.windows.2 In-Reply-To: <20210201013657.1833-1-heng.luo@intel.com> References: <20210201013657.1833-1-heng.luo@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3171 Adds the following files: * IpBlock/Gpio/Include * IpBlock/Gpio/IncludePrivate * IpBlock/Gpio/Library * IpBlock/Gpio/LibraryPrivate Cc: Sai Chaganty Cc: Nate DeSimone Signed-off-by: Heng Luo --- Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCheckCo= nflictLib.h | 43 ++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/DxeG= pioPolicyLib.h | 55 +++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpio= HelpersLib.h | 105 ++++++++++++++++++++++++= +++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpio= NameBufferLib.h | 23 +++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/Gpio= PrivateLib.h | 1197 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfli= ctLib/BaseGpioCheckConflictLib.c | 140 ++++++++++++++++++++++++= ++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfli= ctLib/BaseGpioCheckConflictLib.inf | 29 +++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfli= ctLibNull/BaseGpioCheckConflictLibNull.c | 35 +++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConfli= ctLibNull/BaseGpioCheckConflictLibNull.inf | 26 ++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Gp= ioInit.c | 558 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Gp= ioLib.c | 2387 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Gp= ioLibrary.h | 82 ++++++++++++++++++++++++= ++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Gp= ioNames.c | 86 ++++++++++++++++++++++++= ++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Gp= ioNativeLib.c | 193 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/Pe= iDxeSmmGpioLib.inf | 49 ++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelp= ersLibNull/BaseGpioHelpersLibNull.c | 119 ++++++++++++++++++++++++= ++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelp= ersLibNull/BaseGpioHelpersLibNull.inf | 26 ++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameB= ufferLib/DxeGpioNameBufferLib.inf | 32 ++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameB= ufferLib/GpioNameBufferDxe.c | 19 +++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolic= yLib/DxeGpioPolicyLib.c | 87 ++++++++++++++++++++++++= ++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioPolic= yLib/DxeGpioPolicyLib.inf | 31 ++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpi= oPrivateLib/GpioNamesVer2.c | 88 ++++++++++++++++++++++++= +++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpi= oPrivateLib/GpioPrivateLib.c | 395 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpi= oPrivateLib/GpioPrivateLibVer2.c | 131 ++++++++++++++++++++++++= ++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpi= oPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf | 46 +++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpe= rsLib/PeiGpioHelpersLib.c | 413 ++++++++++++++++++++++++= +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpe= rsLib/PeiGpioHelpersLib.inf | 48 ++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameB= ufferLib/GpioNameBufferPei.c | 67 +++++++++++++++++++++++++ Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameB= ufferLib/PeiGpioNameBufferLib.inf | 35 +++++++++++++ 29 files changed, 6545 insertions(+) diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library= /GpioCheckConflictLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/In= clude/Library/GpioCheckConflictLib.h new file mode 100644 index 0000000000..5e3dd90ae6 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Include/Library/GpioCh= eckConflictLib.h @@ -0,0 +1,43 @@ +/** @file=0D + Header file for checking Gpio PadMode conflict.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _GPIO_CHECK_CONFLICT_LIB_H_=0D +#define _GPIO_CHECK_CONFLICT_LIB_H_=0D +=0D +#include =0D +#include =0D +#include =0D +=0D +extern EFI_GUID gGpioCheckConflictHobGuid;=0D +=0D +typedef struct {=0D + GPIO_PAD GpioPad;=0D + UINT32 GpioPadMode:5;=0D + UINT32 Reserved:27;=0D +} GPIO_PAD_MODE_INFO;=0D +=0D +/**=0D + Check Gpio PadMode conflict and report it.=0D +**/=0D +VOID=0D +GpioCheckConflict (=0D + VOID=0D + );=0D +=0D +/**=0D + This library will create one Hob for each Gpio config table=0D + without PadMode is GpioHardwareDefault=0D +=0D + @param[in] GpioDefinition Point to Platform Gpio table=0D + @param[in] GpioTableCount Number of Gpio table entries=0D +**/=0D +VOID=0D +CreateGpioCheckConflictHob (=0D + IN GPIO_INIT_CONFIG *GpioDefinition,=0D + IN UINT32 GpioTableCount=0D + );=0D +=0D +#endif // _GPIO_CHECK_CONFLICT_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/DxeGpioPolicyLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio= /IncludePrivate/Library/DxeGpioPolicyLib.h new file mode 100644 index 0000000000..d86e6624b7 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /DxeGpioPolicyLib.h @@ -0,0 +1,55 @@ +/** @file=0D + DXE Gpio policy library.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _DXE_GPIO_POLICY_LIB_H_=0D +#define _DXE_GPIO_POLICY_LIB_H_=0D +=0D +#include =0D +=0D +/**=0D + Print GPIO_DXE_CONFIG and serial out.=0D +=0D + @param[in] PchPolicy Pointer to a PCH_POLICY_PROTOCOL=0D +**/=0D +VOID=0D +GpioDxePrintConfig (=0D + IN PCH_POLICY_PROTOCOL *PchPolicy=0D + );=0D +=0D +/**=0D + Load DXE Config block default for GPIO=0D +=0D + @param[in] ConfigBlockPointer Pointer to config block=0D +**/=0D +VOID=0D +GpioDxeLoadConfigDefault (=0D + IN VOID *ConfigBlockPointer=0D + );=0D +=0D +/**=0D + Get Gpio config block table size.=0D +=0D + @retval Size of config block=0D +**/=0D +UINT16=0D +GpioDxeGetConfigBlockTotalSize (=0D + VOID=0D + );=0D +=0D +/**=0D + Add Gpio ConfigBlock.=0D +=0D + @param[in] ConfigBlockTableAddress The pointer to config block table= =0D +=0D + @retval EFI_SUCCESS The policy default is initialized.= =0D + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create b= uffer=0D +**/=0D +EFI_STATUS=0D +GpioDxeAddConfigBlock (=0D + IN VOID *ConfigBlockTableAddress=0D + );=0D +=0D +#endif // _DXE_GPIO_POLICY_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioHelpersLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/I= ncludePrivate/Library/GpioHelpersLib.h new file mode 100644 index 0000000000..d2a8d24c8a --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioHelpersLib.h @@ -0,0 +1,105 @@ +/** @file=0D + Header file for GPIO Helpers Lib implementation.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _GPIO_HELPERS_LIB_H_=0D +#define _GPIO_HELPERS_LIB_H_=0D +=0D +#include =0D +=0D +/**=0D + This procedure stores GPIO pad unlock information=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] GpioLockConfig GPIO Lock Configuration=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreUnlockData (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_LOCK_CONFIG GpioLockConfig=0D + );=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which PadConfig needs t= o be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToLock DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockPadConfigData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + );=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which Output state need= s to be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToLock DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockOutputData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + );=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which PadConfig is su= pposed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockPadConfigMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + );=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which Output is suppo= sed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockOutputMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + );=0D +=0D +/**=0D + Returns Gpio Override Level1 Information=0D +=0D + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled=0D +**/=0D +BOOLEAN=0D +GpioOverrideLevel1Enabled (=0D + VOID=0D + );=0D +#endif // _GPIO_HELPERS_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioNameBufferLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpi= o/IncludePrivate/Library/GpioNameBufferLib.h new file mode 100644 index 0000000000..c60709c637 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioNameBufferLib.h @@ -0,0 +1,23 @@ +/** @file=0D + Header file for GpioMemLib. This library provides GpioLib with static me= mory to hold GpioName.=0D + Static memory is handled differently in PEI and DXE phase. For PEI pre m= em we use private HOB to store=0D + gpio name since .data section is read only. For PEI post mem and DXE sim= ple static buffer is used.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _GPIO_NAME_BUFFER_LIB_H_=0D +#define _GPIO_NAME_BUFFER_LIB_H_=0D +=0D +#define GPIO_NAME_LENGTH_MAX 32=0D +=0D +/**=0D + Returns pointer to the global buffer to be used by GpioNamesLib=0D +=0D + @retval CHAR8* Pointer to the buffer=0D +**/=0D +CHAR8*=0D +GpioGetStaticNameBuffer (=0D + VOID=0D + );=0D +#endif=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/= Library/GpioPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/I= ncludePrivate/Library/GpioPrivateLib.h new file mode 100644 index 0000000000..be41f80c24 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library= /GpioPrivateLib.h @@ -0,0 +1,1197 @@ +/** @file=0D + Header file for GpioPrivateLib.=0D + All function in this library is available for PEI, DXE, and SMM,=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _GPIO_PRIVATE_LIB_H_=0D +#define _GPIO_PRIVATE_LIB_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + GPIO Standby State configuration=0D + Standby State options for GPIO Pads=0D +**/=0D +typedef enum {=0D + GpioIosStateDefault =3D 0x0,=0D + GpioIosStateLatchLastValue =3D (0x0 << 1) | 0x01, ///< Latch last valu= e driven on TX, TX Enable and RX Enable=0D + GpioIosStateTx0Rx0RxDis =3D (0x1 << 1) | 0x01, ///< TX: 0, RX: 0 (i= nternally), RX disabled=0D + GpioIosStateTx0Rx1RxDis =3D (0x2 << 1) | 0x01, ///< TX: 0, RX: 1 (i= nternally), RX disabled=0D + GpioIosStateTx1Rx0RxDis =3D (0x3 << 1) | 0x01, ///< TX: 1, RX: 0 (i= nternally), RX disabled=0D + GpioIosStateTx1Rx1RxDis =3D (0x4 << 1) | 0x01, ///< TX: 1, RX: 1 (i= nternally), RX disabled=0D + GpioIosStateTx0RxEn =3D (0x5 << 1) | 0x01, ///< TX: 0, RX enabl= ed=0D + GpioIosStateTx1RxEn =3D (0x6 << 1) | 0x01, ///< TX: 1, RX enabl= ed=0D + GpioIosStateHizRx0 =3D (0x7 << 1) | 0x01, ///< Hi-Z, RX: 0 (in= ternally)=0D + GpioIosStateHizRx1 =3D (0x8 << 1) | 0x01, ///< Hi-Z, RX: 1 (in= ternally)=0D + GpioIosStateTxDisRxEn =3D (0x9 << 1) | 0x01, ///< TX Disabled and= RX Enabled (i.e. wake or interrupt)=0D + GpioIosStateMasked =3D (0xF << 1) | 0x01 ///< IO Standby sign= al is masked for this pad. In this mode, a pad operates as if IOStandby has= not been asserted.=0D +} GPIO_IOSTANDBY_STATE;=0D +=0D +/**=0D + GPIO Standby Term configuration=0D + Standby Termination options for GPIO Pads=0D +**/=0D +typedef enum {=0D + GpioIosTermDefault =3D 0x00,=0D + GpioIosTermSame =3D (0x00 << 1) | 0x01, ///< Same as state sp= ecified in Term=0D + GpioIosTermPuDisPdDis =3D (0x01 << 1) | 0x01, ///< Disable Pullup a= nd Pulldown=0D + GpioIosTermPuDisPdEn =3D (0x02 << 1) | 0x01, ///< Enable Pulldown= =0D + GpioIosTermPuEnPdDis =3D (0x03 << 1) | 0x01 ///< Enable Pullup=0D +} GPIO_IOSTANDBY_TERM;=0D +=0D +//=0D +// Structure for native pin data=0D +//=0D +typedef struct {=0D + GPIO_PAD Pad;=0D + GPIO_PAD_MODE Mode;=0D + GPIO_IOSTANDBY_STATE IosState;=0D + GPIO_IOSTANDBY_TERM IosTerm;=0D +} GPIO_PAD_NATIVE_FUNCTION;=0D +=0D +//=0D +// Structure for Serial GPIO pin definition=0D +//=0D +typedef struct {=0D + GPIO_PAD_NATIVE_FUNCTION Sclock;=0D + GPIO_PAD_NATIVE_FUNCTION Sload;=0D + GPIO_PAD_NATIVE_FUNCTION Sdataout;=0D +} SGPIO_PINS;=0D +=0D +//=0D +// Structure for USB Virtual Wire OverCurrent Pad Mode group=0D +//=0D +typedef struct {=0D + GPIO_PAD OcRxPad;=0D + GPIO_PAD OcTxPad;=0D +} GPIO_VWOC_FUNCTION;=0D +=0D +//=0D +// Below defines are based on GPIO_CONFIG structure fields=0D +//=0D +#define B_GPIO_PAD_MODE_MASK 0xF=0D +#define N_GPIO_PAD_MODE_BIT_POS 0=0D +#define B_GPIO_HOSTSW_OWN_MASK 0x3=0D +#define N_GPIO_HOSTSW_OWN_BIT_POS 0=0D +#define B_GPIO_DIRECTION_MASK 0x1F=0D +#define B_GPIO_DIRECTION_DIR_MASK 0x7=0D +#define N_GPIO_DIRECTION_DIR_BIT_POS 0=0D +#define B_GPIO_DIRECTION_INV_MASK 0x18=0D +#define N_GPIO_DIRECTION_INV_BIT_POS 3=0D +#define B_GPIO_OUTPUT_MASK 0x3=0D +#define N_GPIO_OUTPUT_BIT_POS 0=0D +#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS 0=0D +#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS 5=0D +#define B_GPIO_RESET_CONFIG_RESET_MASK 0x3F=0D +#define N_GPIO_RESET_CONFIG_OLD_RESET_TYPE BIT1=0D +#define B_GPIO_RESET_CONFIG_OLD_RESET_MASK 0xF=0D +#define N_GPIO_RESET_CONFIG_RESET_BIT_POS 0=0D +#define B_GPIO_RESET_CONFIG_GPD_RESET_MASK (BIT5 | BIT4)=0D +#define B_GPIO_RESET_CONFIG_GPP_RESET_MASK (BIT3 | BIT2)=0D +#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS 0=0D +#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS 0=0D +#define B_GPIO_GPIO_IOSTANDBY_STATE_MASK ((0xF << 1) | 0x01= )=0D +#define B_GPIO_GPIO_IOSTANDBY_STATE_POS 0=0D +#define B_GPIO_GPIO_IOSTANDBY_TERM_MASK ((0x2 << 1) | 0x01= )=0D +#define B_GPIO_GPIO_IOSTANDBY_TERM_POS 0=0D +=0D +//=0D +// Structure for storing information about registers offset, community,=0D +// maximal pad number for available groups=0D +//=0D +typedef struct {=0D + PCH_SBI_PID Community;=0D + UINT16 PadOwnOffset;=0D + UINT16 HostOwnOffset;=0D + UINT16 GpiIsOffset;=0D + UINT16 GpiIeOffset;=0D + UINT16 GpiGpeStsOffset;=0D + UINT16 GpiGpeEnOffset;=0D + UINT16 SmiStsOffset;=0D + UINT16 SmiEnOffset;=0D + UINT16 NmiStsOffset;=0D + UINT16 NmiEnOffset;=0D + UINT16 PadCfgLockOffset;=0D + UINT16 PadCfgLockTxOffset;=0D + UINT16 PadCfgOffset;=0D + UINT16 PadPerGroup;=0D +} GPIO_GROUP_INFO;=0D +=0D +//=0D +// If in GPIO_GROUP_INFO structure certain register doesn't exist=0D +// it will have value equal to NO_REGISTER_FOR_PROPERTY=0D +//=0D +#define NO_REGISTER_FOR_PROPERTY 0xFFFF=0D +=0D +#define GPIO_PAD_DEF(Group,Pad) (UINT32)(((Group) << 16) + = (Pad))=0D +#define GPIO_GROUP_DEF(GroupIndex,ChipsetId) ((GroupIndex) | ((ChipsetId= ) << 8))=0D +#define GPIO_GET_GROUP_INDEX(Group) ((Group) & 0x1F)=0D +#define GPIO_GET_GROUP_FROM_PAD(GpioPad) (((GpioPad) & 0x0F1F0000) >= > 16)=0D +#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) GPIO_GET_GROUP_INDEX (GPIO_= GET_GROUP_FROM_PAD(GpioPad))=0D +#define GPIO_GET_PAD_NUMBER(GpioPad) ((GpioPad) & 0x1FF)=0D +#define GPIO_GET_CHIPSET_ID(GpioPad) (((GpioPad) >> 24) & 0xF)=0D +=0D +#define GPIO_GET_PAD_POSITION(PadNumber) ((PadNumber) % 32)=0D +#define GPIO_GET_DW_NUM(PadNumber) ((PadNumber) / 32u)=0D +=0D +/**=0D + This procedure will retrieve address and length of GPIO info table=0D +=0D + @param[out] GpioGroupInfoTableLength Length of GPIO group table=0D +=0D + @retval Pointer to GPIO group table=0D +**/=0D +CONST GPIO_GROUP_INFO*=0D +GpioGetGroupInfoTable (=0D + OUT UINT32 *GpioGroupInfoTableLength=0D + );=0D +=0D +typedef struct {=0D + CONST CHAR8* GpioGroupPrefix;=0D + CONST GPIO_PAD FirstUniqueGpio;=0D + CONST CHAR8** GroupUniqueNames;=0D + CONST UINT32 UniqueNamesTableSize;=0D +} GPIO_GROUP_NAME_INFO;=0D +=0D +//=0D +// Helper macros for initializing GPIO_GROUP_NAME_INFO structures=0D +//=0D +#define GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTable) \= =0D + {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE (GroupUni= queNamesTable)}=0D +=0D +#define GPIO_GROUP_NAME_BASIC(GroupName) \=0D + {GroupName, 0, NULL, 0}=0D +=0D +/**=0D + Returns GPIO_GROUP_NAME_INFO corresponding to the give GpioPad=0D +=0D + @param[in] GroupIndex Group index=0D +=0D + @retval GPIO_GROUP_NAME_INFO* Pointer to the GPIO_GROUP_NAME_INFO=0D + @retval NULL If no group descriptor was found=0D +**/=0D +CONST=0D +GPIO_GROUP_NAME_INFO*=0D +GpioGetGroupNameInfo (=0D + IN UINT32 GroupIndex=0D + );=0D +=0D +/**=0D + Get GPIO Chipset ID specific to PCH generation and series=0D +**/=0D +UINT32=0D +GpioGetThisChipsetId (=0D + VOID=0D + );=0D +=0D +/**=0D + This procedure is used to check if GpioPad is valid for certain chipset= =0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE This pin is valid on this chipset=0D + FALSE Incorrect pin=0D +**/=0D +BOOLEAN=0D +GpioIsCorrectPadForThisChipset (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +/**=0D + Generates GPIO name from GpioPad=0D + This function returns pointer to the static buffer.=0D +=0D + @param[in] GpioPad GpioPad=0D +=0D + @retval CHAR8* Pointer to the GPIO name=0D +**/=0D +CHAR8*=0D +GpioName (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +/**=0D + Generates GPIO name from GpioNativePad=0D + This function returns pointer to the static buffer.=0D +=0D + @param[in] GpioNativePad GpioNativePad=0D +=0D + @retval CHAR8* Pointer to the GPIO name=0D +**/=0D +CHAR8*=0D +GpioPinMuxName (=0D + IN GPIO_NATIVE_PAD GpioNativePad=0D + );=0D +=0D +/**=0D + Generates GPIO Pad Termination string=0D + This function returns pointer to the static buffer.=0D +=0D + @param[in] GpioPadTermination GPIO Pad Termination=0D +=0D + @retval CHAR8* Painter to the pad termianation string=0D +**/=0D +CHAR8*=0D +GpioGetPadTerminationString (=0D + IN GPIO_ELECTRICAL_CONFIG PadTermination=0D + );=0D +=0D +/**=0D + This procedure will get value of selected gpio register=0D +=0D + @param[in] Group GPIO group number=0D + @param[in] Offset GPIO register offset=0D + @param[out] RegVal Value of gpio register=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetReg (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 Offset,=0D + OUT UINT32 *RegVal=0D + );=0D +=0D +/**=0D + This procedure will set value of selected gpio register=0D +=0D + @param[in] Group GPIO group number=0D + @param[in] Offset GPIO register offset=0D + @param[in] RegVal Value of gpio register=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetReg (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 Offset,=0D + IN UINT32 RegVal=0D + );=0D +=0D +/**=0D + This procedure is used by PchSmiDispatcher and will return information=0D + needed to register GPI SMI.=0D +=0D + @param[in] Index GPI SMI number=0D + @param[out] GpioPin GPIO pin=0D + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi R= egisters=0D + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN register=0D + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetPadAndSmiRegs (=0D + IN UINT32 Index,=0D + OUT GPIO_PAD *GpioPin,=0D + OUT UINT8 *GpiSmiBitOffset,=0D + OUT UINT32 *GpiHostSwOwnRegAddress,=0D + OUT UINT32 *GpiSmiStsRegAddress=0D + );=0D +=0D +/**=0D + This procedure will set GPIO Driver IRQ number=0D +=0D + @param[in] Irq Irq number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid IRQ number=0D +**/=0D +EFI_STATUS=0D +GpioSetIrq (=0D + IN UINT8 Irq=0D + );=0D +=0D +/**=0D + This function provides GPIO Community PortIDs=0D +=0D + @param[out] NativePinsTable Table with GPIO COMMx SBI Por= tIDs=0D +=0D + @retval Number of communities=0D +**/=0D +UINT32=0D +GpioGetComSbiPortIds (=0D + OUT PCH_SBI_PID **GpioComSbiIds=0D + );=0D +=0D +/**=0D + This function provides list of GPIO for which IO Standby State configura= tion=0D + has to be set as 'Masked'=0D +=0D + @param[out] GpioPadsList Table with pads=0D +=0D + @retval Number of pads=0D +**/=0D +UINT32=0D +GpioGetIoStandbyStateConfigurationPadsList (=0D + OUT GPIO_PAD_NATIVE_FUNCTION **GpioPadsList=0D + );=0D +=0D +=0D +/**=0D + This procedure will perform special handling of GPP_A_12.=0D +=0D + @param[in] None=0D +=0D + @retval None=0D +**/=0D +VOID=0D +GpioA12SpecialHandling (=0D + VOID=0D + );=0D +=0D +//=0D +// Structure which stores information needed to map GPIO Group=0D +// to 1-Tier GPE. Configuration is needed both in PMC and GPIO IP.=0D +// Because GPE_DWx can handle only 32 pins only single double word can=0D +// be mapped at a time. Each DW for a group has different configuration in= PMC and GPIO=0D +//=0D +typedef struct {=0D + GPIO_GROUP Group;=0D + UINT8 GroupDw;=0D + UINT8 PmcGpeDwxVal;=0D +} GPIO_GROUP_TO_GPE_MAPPING;=0D +=0D +/**=0D + Get information for GPIO Group required to program GPIO and PMC for desi= red 1-Tier GPE mapping=0D +=0D + @param[out] GpioGroupToGpeMapping Table with GPIO Group to GPE ma= pping=0D + @param[out] GpioGroupToGpeMappingLength GPIO Group to GPE mapping table= length=0D +**/=0D +VOID=0D +GpioGetGroupToGpeMapping (=0D + OUT GPIO_GROUP_TO_GPE_MAPPING **GpioGroupToGpeMapping,=0D + OUT UINT32 *GpioGroupToGpeMappingLength=0D + );=0D +=0D +/**=0D + This procedure will return Port ID of GPIO Community from GpioPad=0D +=0D + @param[in] GpioPad GpioPad=0D +=0D + @retval GpioCommunityPortId Port ID of GPIO Community=0D +**/=0D +UINT8=0D +GpioGetGpioCommunityPortIdFromGpioPad (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +/**=0D + This procedure will return PadCfg address from GpioPad=0D +=0D + @param[in] GpioPad GpioPad=0D +=0D + @retval GpioPadCfgAddress PadCfg Address of GpioPad=0D +**/=0D +UINT32=0D +GpioGetGpioPadCfgAddressFromGpioPad (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +/**=0D + This procedure is used to unlock all GPIO pads.=0D + This function can only be called when platform is still in HOSTIA_BOOT_S= AI.=0D +**/=0D +VOID=0D +GpioUnlockAllPads (=0D + VOID=0D + );=0D +=0D +/**=0D + This procedure will check if GpioPad is owned by host.=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE GPIO pad is owned by host=0D + @retval FALSE GPIO pad is not owned by host and should not be= used with GPIO lib API=0D +**/=0D +BOOLEAN=0D +GpioIsPadHostOwned (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +=0D +/**=0D + This procedure will check if GpioPad argument is valid.=0D + Function will check below conditions:=0D + - GpioPad represents a pad for current PCH=0D + - GpioPad belongs to valid GpioGroup=0D + - GPIO PadNumber is not greater than number of pads for this group=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE GPIO pad is valid and can be used with GPIO lib= API=0D + @retval FALSE GPIO pad is invalid and cannot be used with GPI= O lib API=0D +**/=0D +BOOLEAN=0D +GpioIsPadValid (=0D + IN GPIO_PAD GpioPad=0D + );=0D +=0D +/**=0D + This procedure will read GPIO Pad Configuration register=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1=0D +=0D + @retval PadCfgRegValue PADCFG_DWx value=0D +**/=0D +UINT32=0D +GpioReadPadCfgReg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT8 DwReg=0D + );=0D +=0D +/**=0D + This procedure will write or read GPIO Pad Configuration register=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1=0D + @param[in] PadCfgAndMask Mask to be AND'ed with PADCFG reg value= =0D + @param[in] PadCfgOrMask Mask to be OR'ed with PADCFG reg value=0D +=0D + @retval none=0D +**/=0D +VOID=0D +GpioWritePadCfgReg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT8 DwReg,=0D + IN UINT32 PadCfgAndMask,=0D + IN UINT32 PadCfgOrMask=0D + );=0D +=0D +/**=0D + This procedure will Enable USB Virtual Wire Overcurrent pin=0D +=0D + @param[in] GpioPad GPIO Pad=0D +=0D + @retval EFI_SUCCESS=0D +**/=0D +EFI_STATUS=0D +GpioSetVwOverCurrentPin (=0D + IN GPIO_VWOC_FUNCTION GpioPad=0D + );=0D +=0D +/**=0D + This procedure will set Native Function IOSF-SB Virtual Wire Message Gen= eration bit=0D + in DW0 of requested GPIO Pad=0D +=0D + @param[in] GPIO_PAD GpioPad=0D +**/=0D +VOID=0D +GpioSetNafVweBit (=0D + IN CONST GPIO_PAD PadCfg=0D + );=0D +=0D +/**=0D + This procedure will set GPIO mode=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] PadModeValue GPIO pad mode value=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetPadMode (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_PAD_MODE PadModeValue=0D + );=0D +=0D +/**=0D + This procedure will set GPIO pad to native mode.=0D + To be used if no other settings are to be configured when enabling nativ= e mode.=0D +=0D + @param[in] GpioNativePad GPIO Pad with native mode information=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetNativePad (=0D + IN GPIO_NATIVE_PAD GpioNativePad=0D + );=0D +=0D +/**=0D + This procedure will set GPIO pad to native function based on provided na= tive function=0D + and platform muxing selection (if needed).=0D +=0D + @param[in] PadFunction PadMode for a specific native signal. Pl= ease refer to GpioNativePads.h=0D + @param[in] PinMux GPIO Native pin mux platform config.=0D + This argument is optional and needs to b= e=0D + provided only if feature can be enabled= =0D + on multiple pads=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetNativePadByFunction (=0D + IN UINT32 PadFunction,=0D + IN UINT32 PinMux=0D + );=0D +=0D +/**=0D + This procedure will get GPIO mode=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadModeValue GPIO pad mode value=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetPadMode (=0D + IN GPIO_PAD GpioPad,=0D + OUT GPIO_PAD_MODE *PadModeValue=0D + );=0D +=0D +/**=0D + This procedure will check if group is within DeepSleepWell.=0D +=0D + @param[in] Group GPIO Group=0D +=0D + @retval GroupWell TRUE: This is DSW Group=0D + FALSE: This is not DSW Group=0D +**/=0D +BOOLEAN=0D +GpioIsDswGroup (=0D + IN GPIO_GROUP Group=0D + );=0D +=0D +/**=0D + The function performs GPIO Power Management programming.=0D +**/=0D +VOID=0D +GpioConfigurePm (=0D + VOID=0D + );=0D +=0D +/**=0D + This function performs initial IO Standby State related configurations=0D +**/=0D +VOID=0D +GpioConfigureIoStandbyState (=0D + VOID=0D + );=0D +=0D +/**=0D + This function enables SCS SD Card controller card detect pin=0D +=0D + @param[in] none=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableScsSdCardDetect (=0D + VOID=0D + );=0D +=0D +/**=0D + This function sets HDA SSP interface pins into native mode=0D +=0D + @param[in] SspInterfaceNumber SSPx interface number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableHdaSsp (=0D + IN UINT32 SspInterfaceNumber=0D + );=0D +=0D +/**=0D + This function sets HDA SSP Master Clock into native mode=0D +=0D + @param[in] MclkIndex MCLK index=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableHdaSspMasterClock (=0D + IN UINT32 MclkIndex=0D + );=0D +=0D +/**=0D + This function sets HDA SoundWire interface pins into native mode=0D +=0D + @param[in] SndwInterfaceNumber SNDWx interface number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableHdaSndw (=0D + IN UINT32 SndwInterfaceNumber=0D + );=0D +=0D +/**=0D + This function provides SPI IO pin for Touch Host Controller=0D +=0D + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1=0D + @param[in] IoIndex IoIndex Valid from 0 (SPI_IO_0) to= 3 (SPI_IO_3)=0D +=0D + @retval NativePin Native Pin Configuration, 0 if Spi= Index or IoIndex is invalid=0D +**/=0D +GPIO_PAD_NATIVE_FUNCTION=0D +GpioGetThcSpiIo (=0D + IN UINT32 SpiIndex,=0D + IN UINT32 IoIndex=0D + );=0D +=0D +/**=0D + This function provides SPI ChipSelect pin for Touch Host Controller=0D +=0D + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1=0D +=0D + @retval NativePin Native Pin Configuration, 0 if Spi= Index is invalid=0D +**/=0D +GPIO_PAD_NATIVE_FUNCTION=0D +GpioGetThcSpiCs (=0D + IN UINT32 SpiIndex=0D + );=0D +=0D +/**=0D + This function provides SPI Clock pin for Touch Host Controller=0D +=0D + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1=0D +=0D + @retval NativePin Native Pin Configuration, 0 if Spi= Index is invalid=0D +**/=0D +GPIO_PAD_NATIVE_FUNCTION=0D +GpioGetThcSpiClk (=0D + IN UINT32 SpiIndex=0D + );=0D +=0D +/**=0D + This function provides SPI Reset pin for Touch Host Controller=0D +=0D + @param[in] SpiIndex SPI1 or SPI2 - 0 or 1=0D +=0D + @retval NativePin Native Pin Configuration, 0 if Spi= Index is invalid=0D +**/=0D +GPIO_PAD_NATIVE_FUNCTION=0D +GpioGetThcSpiReset (=0D + IN UINT32 SpiIndex=0D + );=0D +=0D +/**=0D + This function sets SMBUS controller pins into native mode=0D +=0D + @param[in] none=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSmbus (=0D + VOID=0D + );=0D +=0D +/**=0D + This function sets SMBUS ALERT pins into native mode=0D +=0D + @param[in] none=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSmbusAlert (=0D + VOID=0D + );=0D +=0D +/**=0D + This function provides Serial GPIO pins=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[out] SgpioPins SATA Serial GPIO pins=0D +**/=0D +VOID=0D +GpioGetSataSgpioPins (=0D + IN UINT32 SataCtrlIndex,=0D + OUT SGPIO_PINS *SgpioPins=0D + );=0D +=0D +/**=0D + This function sets Serial GPIO pins into native mode=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[in] SataPort SATA port number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSataSgpio (=0D + IN UINT32 SataCtrlIndex=0D + );=0D +=0D +/**=0D + This function enables USB OverCurrent pins by setting=0D + USB2 OCB pins into native mode=0D +=0D + @param[in] OcPinNumber USB OC pin number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableUsbOverCurrent (=0D + IN UINTN OcPinNumber=0D + );=0D +=0D +/**=0D + This function enables USB Virtual Wire OverCurrent pins by OcPinNumber.= =0D +=0D + @param[in] OcPinNumber USB OC pin number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableUsbVwOverCurrent (=0D + IN UINTN OcPinNumber=0D + );=0D +=0D +/**=0D + This function sets SATA DevSlp pins into native mode=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[in] SataPort SATA port number=0D + @param[in] ResetType GPIO reset type (see GPIO_RESET_CONFIG i= n GpioConfig.h)=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSataDevSlpPin (=0D + IN UINT32 SataCtrlIndex,=0D + IN UINTN SataPort,=0D + IN UINT32 ResetType=0D + );=0D +=0D +/**=0D + This function checks if SataDevSlp pin is in native mode=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[in] SataPort SATA port=0D + @param[out] DevSlpPad DevSlpPad=0D + This is an optional parameter and may be= NULL.=0D +=0D + @retval TRUE DevSlp is in native mode=0D + FALSE DevSlp is not in native mode=0D +**/=0D +BOOLEAN=0D +GpioIsSataDevSlpPinEnabled (=0D + IN UINT32 SataCtrlIndex,=0D + IN UINTN SataPort,=0D + OUT GPIO_PAD *DevSlpPad OPTIONAL=0D + );=0D +=0D +/**=0D + This function sets SATAGPx pin into native mode=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[in] SataPort SATA port number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSataGpPin (=0D + IN UINT32 SataCtrlIndex,=0D + IN UINTN SataPort=0D + );=0D +=0D +/**=0D + This function provides SATA GP pin data=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @param[in] SataPort SATA port number=0D + @param[out] NativePin SATA GP pin=0D +**/=0D +VOID=0D +GpioGetSataGpPin (=0D + IN UINT32 SataCtrlIndex,=0D + IN UINTN SataPort,=0D + OUT GPIO_PAD_NATIVE_FUNCTION *NativePin=0D + );=0D +=0D +/**=0D + This function sets SATA LED pin into native mode. SATA LED indicates=0D + SATA controller activity=0D +=0D + @param[in] SataCtrlIndex SATA controller index=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableSataLed (=0D + IN UINT32 SataCtrlIndex=0D + );=0D +=0D +/**=0D + Returns pad for given CLKREQ# index.=0D +=0D + @param[in] ClkreqIndex CLKREQ# number=0D +=0D + @return CLKREQ# pad.=0D +**/=0D +GPIO_PAD=0D +GpioGetClkreqPad (=0D + IN UINT32 ClkreqIndex=0D + );=0D +=0D +/**=0D + Enables CLKREQ# pad in native mode.=0D +=0D + @param[in] ClkreqIndex CLKREQ# number=0D +=0D + @return none=0D +**/=0D +VOID=0D +GpioEnableClkreq (=0D + IN UINT32 ClkreqIndex=0D + );=0D +=0D +/**=0D + This function sets PCHHOT pin into native mode=0D +=0D + @param[in] none=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnablePchHot (=0D + VOID=0D + );=0D +=0D +/**=0D + This function sets VRALERTB pin into native mode=0D +=0D + @param[in] none=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableVrAlert (=0D + VOID=0D + );=0D +=0D +/**=0D + This function sets CPU GP pins into native mode=0D +=0D + @param[in] CpuGpPinNum CPU GP pin number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableCpuGpPin (=0D + IN UINT32 CpuGpPinNum=0D + );=0D +=0D +/**=0D +This function sets CPU C10 Gate pins into native mode=0D +=0D +@retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableCpuC10GatePin (=0D + VOID=0D + );=0D +=0D +//=0D +// DDPx pins=0D +//=0D +typedef enum {=0D + GpioDdp1 =3D 0x01,=0D + GpioDdp2 =3D 0x02,=0D + GpioDdp3 =3D 0x03,=0D + GpioDdp4 =3D 0x04,=0D + GpioDdpA =3D 0x10,=0D + GpioDdpB =3D 0x11,=0D + GpioDdpC =3D 0x12,=0D + GpioDdpD =3D 0x13,=0D + GpioDdpF =3D 0x15,=0D +} GPIO_DDP;=0D +=0D +/**=0D + This function sets DDP pins into native mode=0D +=0D + @param[in] DdpInterface DDPx interface=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableDpInterface (=0D + IN GPIO_DDP DdpInterface=0D + );=0D +=0D +//=0D +// DDI Port TBT_LSX interface=0D +//=0D +typedef enum {=0D + GpioTbtLsxDdi1,=0D + GpioTbtLsxDdi2,=0D + GpioTbtLsxDdi3,=0D + GpioTbtLsxDdi4,=0D + GpioTbtLsxDdi5,=0D + GpioTbtLsxDdi6=0D +} GPIO_TBT_LSX;=0D +=0D +/**=0D + This function sets TBT_LSx pin into native mode=0D +=0D + @param[in] TbtLsxDdiPort TBT_LSx DDI Port Number=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableTbtLsxInterface (=0D + IN GPIO_TBT_LSX TbtLsxDdiPort=0D + );=0D +=0D +/**=0D + This function configures GPIO connection between CNVi and CRF=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioConfigureCnviCrfConnection (=0D + VOID=0D + );=0D +=0D +/**=0D + This function sets CNVi Bluetooth Enable value=0D +=0D + @param[in] Value CNVi BT enable value=0D + 0: Disable, 1: Enable=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioSetCnviBtEnState (=0D + IN UINT32 Value=0D + );=0D +=0D +/**=0D + This function sets CNVi Bluetooth Wireless Charging support=0D +=0D + @param[in] BtWirelessCharging CNVi BT Wireless Charging support=0D + 0: Normal BT operation (no Wireless Char= ging support)=0D + 1: Enable BT Wireless Charging=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioSetCnviBtWirelessCharging (=0D + IN UINT32 BtWirelessCharging=0D + );=0D +=0D +/**=0D + This function enables and configures CNVi Bluetooth Host wake-up interru= pt=0D +=0D + @param[in] None=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioConfigureCnviBtHostWakeInt (=0D + VOID=0D + );=0D +=0D +/**=0D + This function enables IMGU CLKOUT native pin=0D +=0D + @param[in] ImguClkOutPinIndex The index of IMGU CLKOUT natine pin=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableImguClkOut (=0D + IN UINT8 ImguClkOutPinIndex=0D + );=0D +=0D +/**=0D + Power button debounce configuration=0D + Debounce time can be specified in microseconds. Only certain values acco= rding=0D + to below formula are supported:=0D + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(glitch filter clock period)= .=0D + RTC clock with f =3D 32 KHz is used for glitch filter.=0D + DebounceTime =3D (2 ^ PADCFG_DW2.DEBOUNCE)*(31.25 us).=0D + Supported DebounceTime values are following:=0D + DebounceTime =3D 0 -> Debounce feature disabled=0D + DebounceTime > 0 && < 250us -> Not supported=0D + DebounceTime =3D 250us - 1024000us -> Supported range (DebounceTime =3D= 250us * 2^n)=0D + For values not supported by HW, they will be rounded down to closest sup= ported one=0D +=0D + @param[in] DebounceTime Debounce Time in microseconds=0D + If Debounce Time =3D 0, Debouncer feature wil= l be disabled=0D + Function will set DebounceTime argument to ro= unded supported value=0D +**/=0D +VOID=0D +GpioSetPwrBtnDebounceTimer (=0D + IN UINT32 DebounceTime=0D + );=0D +=0D +=0D +/**=0D + VCCIO level selection=0D +**/=0D +typedef enum {=0D + GpioVcc3v3,=0D + GpioVcc1v8,=0D + MaxVccioSel=0D +} GPIO_VCCIO_SEL;=0D +/**=0D + The function sets VCCIOSEL=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] VccioSel Pad voltage=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED The Pin is owned by others=0D + @retval EFI_INVALID_PARAMETER Invalid group or parameter=0D +**/=0D +EFI_STATUS=0D +GpioSetVccLevel (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_VCCIO_SEL VccioSel=0D + );=0D +=0D +/**=0D + SBU (Sideband use) pins are used as auxiliary signals for Type C connect= or,=0D + which are hard-wired to BSSB_LS natively for debug function.=0D + when USB-C is enablde and debug not needed, disable pins (BSSB) used for= debug through TypeC connector,=0D + program SBU pins to high-Z/open circuit per USB-C spec.=0D +=0D + @param[in] UsbTcPortEnBitmap USB Type C port enabled bitmap=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED SBU pads are not supported=0D + @retval EFI_INVALID_PARAMETER Invalid input parameter=0D +**/=0D +EFI_STATUS=0D +GpioDisableTypeCSbuDebug (=0D + IN UINT32 UsbTcPortEnBitmap=0D + );=0D +=0D +/**=0D + When 2-wire DCI OOB is connected via SBU from Type C port, need set IO S= tandby state to masked (to operate as if no standby signal asserted)=0D + to remain connection in low power state.=0D +=0D + @param[in] DciPortId DCI connection port ID=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED SBU pads are not supported=0D + @retval EFI_INVALID_PARAMETER Invalid input parameter=0D +**/=0D +EFI_STATUS=0D +Gpio2WireDciOobSetting (=0D + IN UINT8 DciPortId=0D + );=0D +=0D +/**=0D + This function enables the virtual wire msg bus from GPIO controller=0D + to FIA. The virtual wire is used to transfer CLKREQ assert/de-assert=0D + msg for CPU PCIe ports. Each of the PCIe ports has its dedicated VW=0D + msg.=0D +=0D + @param[in] PortIndex Index of the CPU PCIe port for which VW= =0D + should be enabled.=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED Failed to set native mode.=0D +**/=0D +EFI_STATUS=0D +GpioEnableCpuPcieVwClkReqMsgBus (=0D + IN UINT32 PortIndex=0D + );=0D +=0D +/**=0D + This function sets Time Sync Gpio into native mode=0D +=0D + @param[in] Index index=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableTimeSync (=0D + IN UINT32 Index=0D + );=0D +=0D +/**=0D + This function sets Tsn into native mode=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioEnableTsn (=0D + VOID=0D + );=0D +=0D +/**=0D + This function is to be used In GpioLockPads() to override a lock request= by SOC code.=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum Register number for current group (parameter = applicable in accessing whole register).=0D + For group which has less then 32 pads per gro= up DwNum must be 0.=0D + @param[out] *UnlockCfgPad DWORD bitmask for pads which are going to be = left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave unlocke= d=0D + @param[out] *UnlockTxPad DWORD bitmask for pads which are going to be = left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave unlocke= d=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid input parameter=0D +**/=0D +EFI_STATUS=0D +GpioUnlockOverride (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + OUT UINT32 *UnlockCfgPad,=0D + OUT UINT32 *UnlockTxPad=0D + );=0D +=0D +/**=0D + Check if 0x13 opcode supported for writing to GPIO lock unlock register= =0D +=0D + @retval TRUE It's supported=0D + @retval FALSE It's not supported=0D +**/=0D +BOOLEAN=0D +IsGpioLockOpcodeSupported (=0D + VOID=0D + );=0D +=0D +/**=0D + Configures IO standby related settings for the GPIO pad.=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] IoStandbyState GPIO pad IO Standby state=0D + @param[in] IoStandbyTerm GPIO pad IO Standby termination=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioConfigurePadIoStandby (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_IOSTANDBY_STATE IoStandbyState,=0D + IN GPIO_IOSTANDBY_TERM IoStandbyTerm=0D + );=0D +=0D +/**=0D + Checks if GPIO PinMux corresponds to I2C4 B=0D +=0D + @param[in] SdaPinMux GPIO pad pinmux for SDA=0D + @param[in] SclPinMux GPIO pad pinmux for SCL=0D +=0D + @retval TRUE PinMux corresponds to I2C4 B=0D + FALSE PinMux equals to I2C4 A=0D +**/=0D +EFI_STATUS=0D +GpioIsSerialIoI2c4bMuxed (=0D + IN UINT32 SdaPinMux,=0D + IN UINT32 SclPinMux=0D + );=0D +=0D +#endif // _GPIO_PRIVATE_LIB_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpi= oCheckConflictLib/BaseGpioCheckConflictLib.c b/Silicon/Intel/TigerlakeSilic= onPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflictLi= b.c new file mode 100644 index 0000000000..5a6360931b --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckC= onflictLib/BaseGpioCheckConflictLib.c @@ -0,0 +1,140 @@ +/** @file=0D + Implementation of BaseGpioCheckConflictLib.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Check Gpio PadMode conflict and report it.=0D +=0D + @retval none.=0D +**/=0D +VOID=0D +GpioCheckConflict (=0D + VOID=0D + )=0D +{=0D + EFI_HOB_GUID_TYPE *GpioCheckConflictHob;=0D + GPIO_PAD_MODE_INFO *GpioCheckConflictHobData;=0D + UINT32 HobDataSize;=0D + UINT32 GpioCount;=0D + UINT32 GpioIndex;=0D + GPIO_CONFIG GpioActualConfig;=0D +=0D + GpioCheckConflictHob =3D NULL;=0D + GpioCheckConflictHobData =3D NULL;=0D +=0D + DEBUG ((DEBUG_INFO, "GpioCheckConflict Start..\n"));=0D +=0D + //=0D + // Use Guid to find HOB.=0D + //=0D + GpioCheckConflictHob =3D (EFI_HOB_GUID_TYPE *) GetFirstGuidHob (&gGpioCh= eckConflictHobGuid);=0D + if (GpioCheckConflictHob =3D=3D NULL) {=0D + DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] No GPIO HOB found.\n"));=0D + } else {=0D + while (GpioCheckConflictHob !=3D NULL) {=0D + //=0D + // Find the Data area pointer and Data size from the Hob=0D + //=0D + GpioCheckConflictHobData =3D (GPIO_PAD_MODE_INFO *) GET_GUID_HOB_DAT= A (GpioCheckConflictHob);=0D + HobDataSize =3D GET_GUID_HOB_DATA_SIZE (GpioCheckConflictHob);=0D +=0D + GpioCount =3D HobDataSize / sizeof (GPIO_PAD_MODE_INFO);=0D + DEBUG ((DEBUG_INFO, "[GPIO Conflict Check] Hob : GpioCount =3D %d\n= ", GpioCount));=0D +=0D + //=0D + // Probe Gpio entries in Hob and compare which are conflicted=0D + //=0D + for (GpioIndex =3D 0; GpioIndex < GpioCount ; GpioIndex++) {=0D + GpioGetPadConfig (GpioCheckConflictHobData[GpioIndex].GpioPad, &Gp= ioActualConfig);=0D + if (GpioCheckConflictHobData[GpioIndex].GpioPadMode !=3D GpioActua= lConfig.PadMode) {=0D + DEBUG ((DEBUG_ERROR, "[GPIO Conflict Check] Identified conflict = on pad %a (actual: 0x%X, expected: 0x%X)\n",=0D + GpioName (GpioCheckConflictHobData[GpioIndex].GpioPad),= =0D + GpioActualConfig.PadMode,=0D + GpioCheckConflictHobData[GpioIndex].GpioPadMode));=0D + }=0D + }=0D + //=0D + // Find next Hob and return the Hob pointer by the specific Hob Guid= =0D + //=0D + GpioCheckConflictHob =3D GET_NEXT_HOB (GpioCheckConflictHob);=0D + GpioCheckConflictHob =3D GetNextGuidHob (&gGpioCheckConflictHobGuid,= GpioCheckConflictHob);=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "GpioCheckConflict End.\n"));=0D + }=0D +=0D + return;=0D +}=0D +=0D +/**=0D + This libaray will create one Hob for each Gpio config table=0D + without PadMode is GpioHardwareDefault=0D +=0D + @param[in] GpioDefinition Point to Platform Gpio table=0D + @param[in] GpioTableCount Number of Gpio table entries=0D +=0D + @retval none.=0D +**/=0D +VOID=0D +CreateGpioCheckConflictHob (=0D + IN GPIO_INIT_CONFIG *GpioDefinition,=0D + IN UINT32 GpioTableCount=0D + )=0D +{=0D +=0D + UINT32 Index;=0D + UINT32 GpioIndex;=0D + GPIO_PAD_MODE_INFO *GpioCheckConflictHobData;=0D + UINT16 GpioCount;=0D +=0D + GpioCount =3D 0;=0D + GpioIndex =3D 0;=0D +=0D + DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob Start \n"));=0D +=0D + for (Index =3D 0; Index < GpioTableCount ; Index++) {=0D + if (GpioDefinition[Index].GpioConfig.PadMode =3D=3D GpioHardwareDefaul= t) {=0D + continue;=0D + } else {=0D + //=0D + // Calculate non-default GPIO number=0D + //=0D + GpioCount++;=0D + }=0D + }=0D +=0D + //=0D + // Build a HOB tagged with a GUID for identification and returns=0D + // the start address of GUID HOB data.=0D + //=0D + GpioCheckConflictHobData =3D (GPIO_PAD_MODE_INFO *) BuildGuidHob (&gGpio= CheckConflictHobGuid , GpioCount * sizeof (GPIO_PAD_MODE_INFO));=0D +=0D + //=0D + // Record Non Default Gpio entries to the Hob=0D + //=0D + for (Index =3D 0; Index < GpioTableCount; Index++) {=0D + if (GpioDefinition[Index].GpioConfig.PadMode =3D=3D GpioHardwareDefaul= t) {=0D + continue;=0D + } else {=0D + if (GpioCheckConflictHobData !=3D NULL) {=0D + GpioCheckConflictHobData[GpioIndex].GpioPad =3D GpioDefinition[Ind= ex].GpioPad;=0D + GpioCheckConflictHobData[GpioIndex].GpioPadMode =3D GpioDefinition= [Index].GpioConfig.PadMode;=0D + GpioIndex++;=0D + }=0D + }=0D + }=0D +=0D + DEBUG ((DEBUG_INFO, "CreateGpioCheckConflictHob End \n"));=0D + return;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpi= oCheckConflictLib/BaseGpioCheckConflictLib.inf b/Silicon/Intel/TigerlakeSil= iconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLib/BaseGpioCheckConflict= Lib.inf new file mode 100644 index 0000000000..f7e1de774d --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckC= onflictLib/BaseGpioCheckConflictLib.inf @@ -0,0 +1,29 @@ +## @file=0D +# Component information file for BaseGpioCheckConflictLib.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +[Defines]=0D + INF_VERSION =3D 0x00010017=0D + BASE_NAME =3D BaseGpioCheckConflictLib=0D + FILE_GUID =3D C19A848A-F013-4DBF-9C23-F0F74DEA6F14= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D GpioCheckConflictLib=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + HobLib=0D + GpioLib=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D + BaseGpioCheckConflictLib.c=0D +=0D +[Guids]=0D + gGpioCheckConflictHobGuid=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpi= oCheckConflictLibNull/BaseGpioCheckConflictLibNull.c b/Silicon/Intel/Tigerl= akeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioChe= ckConflictLibNull.c new file mode 100644 index 0000000000..2f83f95b27 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckC= onflictLibNull/BaseGpioCheckConflictLibNull.c @@ -0,0 +1,35 @@ +/** @file=0D + Implementation of BaseGpioCheckConflicLibNull.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +=0D +/**=0D + Check Gpio PadMode conflict and report it.=0D +**/=0D +VOID=0D +GpioCheckConflict (=0D + VOID=0D + )=0D +{=0D + return;=0D +}=0D +=0D +/**=0D + This libaray will create one Hob for each Gpio config table=0D + without PadMode is GpioHardwareDefault=0D +=0D + @param[in] GpioDefinition Point to Platform Gpio table=0D + @param[in] GpioTableCount Number of Gpio table entries=0D +**/=0D +VOID=0D +CreateGpioCheckConflictHob (=0D + IN GPIO_INIT_CONFIG *GpioDefinition,=0D + IN UINT32 GpioTableCount=0D + )=0D +{=0D + return;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpi= oCheckConflictLibNull/BaseGpioCheckConflictLibNull.inf b/Silicon/Intel/Tige= rlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckConflictLibNull/BaseGpioC= heckConflictLibNull.inf new file mode 100644 index 0000000000..1c226d7c16 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/BaseGpioCheckC= onflictLibNull/BaseGpioCheckConflictLibNull.inf @@ -0,0 +1,26 @@ +## @file=0D +# Component information file for BaseGpioCheckConflictLib.=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +[Defines]=0D + INF_VERSION =3D 0x00010017=0D + BASE_NAME =3D BaseGpioCheckConflictLibNull=0D + FILE_GUID =3D C19A848A-F013-4DBF-9C23-F0F74DEA6F14= =0D + MODULE_TYPE =3D BASE=0D + VERSION_STRING =3D 1.0=0D + LIBRARY_CLASS =3D GpioCheckConflictLib=0D +=0D +[LibraryClasses]=0D + DebugLib=0D + HobLib=0D + GpioLib=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D + BaseGpioCheckConflictLibNull.c=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioInit.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Libra= ry/PeiDxeSmmGpioLib/GpioInit.c new file mode 100644 index 0000000000..99dbbf0ca6 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioInit.c @@ -0,0 +1,558 @@ +/** @file=0D + This file contains routines for GPIO initialization=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "GpioLibrary.h"=0D +#include =0D +#include =0D +=0D +//=0D +// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function=0D +// to cache values which will be programmed into respective GPIO registers= =0D +// after all GpioPads are processed. This way MMIO accesses are decreased= =0D +// and instead of doing one programming for one GpioPad there is only=0D +// one access for whole register.=0D +//=0D +typedef struct {=0D + UINT32 HostSoftOwnReg;=0D + UINT32 HostSoftOwnRegMask;=0D + UINT32 GpiGpeEnReg;=0D + UINT32 GpiGpeEnRegMask;=0D + UINT32 GpiNmiEnReg;=0D + UINT32 GpiNmiEnRegMask;=0D + UINT32 GpiSmiEnReg;=0D + UINT32 GpiSmiEnRegMask;=0D + UINT32 ConfigUnlockMask;=0D + UINT32 OutputUnlockMask;=0D +} GPIO_GROUP_DW_DATA;=0D +=0D +//=0D +// GPIO_GROUP_DW_NUMBER contains number of DWords required to=0D +// store Pad data for all groups. Each pad uses one bit.=0D +//=0D +#define GPIO_GROUP_DW_NUMBER 1=0D +=0D +/**=0D + Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock).=0D +=0D + @param[in] PadNumber GPIO pad number=0D + @param[in] GpioConfig GPIO Config data=0D + @param[in out] DwRegsValues Values for GPIO DW Registers=0D +=0D + @retval None=0D +**/=0D +STATIC=0D +VOID=0D +GpioDwRegValueFromGpioConfig (=0D + IN UINT32 PadNumber,=0D + IN CONST GPIO_CONFIG *GpioConfig,=0D + IN OUT GPIO_GROUP_DW_DATA *GroupDwData=0D + )=0D +{=0D + UINT32 PadBitPosition;=0D + UINT32 DwNum;=0D +=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D +=0D + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) {=0D + ASSERT (FALSE);=0D + return;=0D + }=0D + //=0D + // Update value to be programmed in HOSTSW_OWN register=0D + //=0D + GroupDwData[DwNum].HostSoftOwnRegMask |=3D (GpioConfig->HostSoftPadOwn &= 0x1) << PadBitPosition;=0D + GroupDwData[DwNum].HostSoftOwnReg |=3D (GpioConfig->HostSoftPadOwn >> 0x= 1) << PadBitPosition;=0D +=0D + //=0D + // Update value to be programmed in GPI_GPE_EN register=0D + //=0D + GroupDwData[DwNum].GpiGpeEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition;=0D + GroupDwData[DwNum].GpiGpeEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntSci) >> 3) << PadBitPosition;=0D +=0D + //=0D + // Update value to be programmed in GPI_NMI_EN register=0D + //=0D + GroupDwData[DwNum].GpiNmiEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition;=0D + GroupDwData[DwNum].GpiNmiEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntNmi) >> 1) << PadBitPosition;=0D +=0D + //=0D + // Update value to be programmed in GPI_SMI_EN register=0D + GroupDwData[DwNum].GpiSmiEnRegMask |=3D (GpioConfig->InterruptConfig & 0= x1) << PadBitPosition;=0D + GroupDwData[DwNum].GpiSmiEnReg |=3D ((GpioConfig->InterruptConfig & Gpio= IntSmi) >> 2) << PadBitPosition;=0D + if ((GpioConfig->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) {=0D + GroupDwData[DwNum].HostSoftOwnRegMask |=3D 1 << PadBitPosition;=0D + GroupDwData[DwNum].HostSoftOwnReg |=3D 1 << PadBitPosition;=0D + }=0D +=0D + //=0D + // Update information on Pad Configuration Lock=0D + //=0D + GroupDwData[DwNum].ConfigUnlockMask |=3D ((GpioConfig->LockConfig >> 1) = & 0x1) << PadBitPosition;=0D +=0D + //=0D + // Update information on Pad Configuration Lock Tx=0D + //=0D + GroupDwData[DwNum].OutputUnlockMask |=3D ((GpioConfig->LockConfig >> 3) = & 0x1) << PadBitPosition;=0D +=0D + //=0D + // if pad in GpioMode is an output default action should be to leave out= put unlocked=0D + //=0D + if ((GpioConfig->PadMode =3D=3D GpioPadModeGpio) &&=0D + (GpioConfig->Direction =3D=3D GpioDirOut) &&=0D + ((GpioConfig->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D= =3D GpioLockDefault)) {=0D + GroupDwData[DwNum].OutputUnlockMask |=3D 0x1 << PadBitPosition;=0D + }=0D +}=0D +=0D +/**=0D + This internal procedure will scan GPIO initialization table and unlock=0D + all pads present in it=0D +=0D + @param[in] NumberOfItem Number of GPIO pad records in tabl= e=0D + @param[in] GpioInitTableAddress GPIO initialization table=0D + @param[in] Index Index of GPIO Initialization table= record=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioUnlockPadsForAGroup (=0D + IN UINT32 NumberOfItems,=0D + IN GPIO_INIT_CONFIG *GpioInitTableAddress,=0D + IN UINT32 Index=0D + )=0D +{=0D + UINT32 PadsToUnlock[GPIO_GROUP_DW_NUMBER];=0D + UINT32 DwNum;=0D + UINT32 PadBitPosition;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + CONST GPIO_INIT_CONFIG *GpioData;=0D + GPIO_GROUP Group;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + GpioData =3D &GpioInitTableAddress[Index];=0D + Group =3D GpioGetGroupFromGpioPad (GpioData->GpioPad);=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);=0D +=0D + ZeroMem (PadsToUnlock, sizeof (PadsToUnlock));=0D + //=0D + // Loop through pads for one group. If pad belongs to a different group = then=0D + // break and move to register programming.=0D + //=0D + while (Index < NumberOfItems) {=0D +=0D + GpioData =3D &GpioInitTableAddress[Index];=0D + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) = {=0D + //if next pad is from different group then break loop=0D + break;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad);=0D + //=0D + // Check if legal pin number=0D + //=0D + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible r= ange for group %d\n", PadNumber, GroupIndex));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D +=0D + if (DwNum >=3D GPIO_GROUP_DW_NUMBER) {=0D + ASSERT (FALSE);=0D + return EFI_UNSUPPORTED;=0D + }=0D + //=0D + // Update pads which need to be unlocked=0D + //=0D + PadsToUnlock[DwNum] |=3D 0x1 << PadBitPosition;=0D +=0D + //Move to next item=0D + Index++;=0D + }=0D +=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].= PadPerGroup); DwNum++) {=0D + //=0D + // Unlock pads=0D + //=0D + if (PadsToUnlock[DwNum] !=3D 0) {=0D + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);=0D + GpioUnlockPadCfgTxForGroupDw (Group, DwNum, PadsToUnlock[DwNum]);=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will initialize multiple PCH GPIO pins=0D +=0D + @param[in] NumberofItem Number of GPIO pads to be updated= =0D + @param[in] GpioInitTableAddress GPIO initialization table=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioConfigurePch (=0D + IN UINT32 NumberOfItems,=0D + IN GPIO_INIT_CONFIG *GpioInitTableAddress=0D + )=0D +{=0D + UINT32 Index;=0D + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];=0D + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER];=0D + UINT32 PadCfgReg;=0D + GPIO_GROUP_DW_DATA GroupDwData[GPIO_GROUP_DW_NUMBER];=0D + UINT32 DwNum;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + GPIO_PAD_OWN PadOwnVal;=0D + CONST GPIO_INIT_CONFIG *GpioData;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + PCH_SBI_PID GpioCom;=0D +=0D + PadOwnVal =3D GpioPadOwnHost;=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + Index =3D 0;=0D + while (Index < NumberOfItems) {=0D +=0D + GpioData =3D &GpioInitTableAddress[Index];=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad);=0D + GpioCom =3D GpioGroupInfo[GroupIndex].Community;=0D +=0D + DEBUG_CODE_BEGIN();=0D + if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on= this chipset!\n", GpioData->GpioPad));=0D + ASSERT (FALSE);=0D + return EFI_UNSUPPORTED;=0D + }=0D + DEBUG_CODE_END ();=0D +=0D + //=0D + // Unlock pads for a given group which are going to be reconfigured=0D + //=0D + //=0D + // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, lock = settings=0D + // will get back to default only after G3 or DeepSx transition. On the= other hand GpioPads=0D + // configuration is controlled by a configurable type of reset - PadRs= tCfg. This means that if=0D + // PadRstCfg !=3D Powergood GpioPad will have its configuration locked= despite it being not the=0D + // one desired by BIOS. Before reconfiguring all pads they will get un= locked.=0D + //=0D + GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, Index);= =0D +=0D + ZeroMem (GroupDwData, sizeof (GroupDwData));=0D + //=0D + // Loop through pads for one group. If pad belongs to a different grou= p then=0D + // break and move to register programming.=0D + //=0D + while (Index < NumberOfItems) {=0D +=0D + GpioData =3D &GpioInitTableAddress[Index];=0D + if (GroupIndex !=3D GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)= ) {=0D + //if next pad is from different group then break loop=0D + break;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioData->GpioPad);=0D +=0D + DEBUG_CODE_BEGIN ();=0D + //=0D + // Check if legal pin number=0D + //=0D + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible= range for group %d\n", PadNumber, GroupIndex));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Check if selected GPIO Pad is not owned by CSME/ISH=0D + //=0D + GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal);=0D +=0D + if (PadOwnVal !=3D GpioPadOwnHost) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by host = (Group=3D%d, Pad=3D%d)!\n", GroupIndex, PadNumber));=0D + DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync b= etween CSME and BIOS configuration. \n"));=0D + DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should not = do any configuration by BIOS.\n"));=0D + //Move to next item=0D + Index++;=0D + continue;=0D + }=0D +=0D + //=0D + // Check if Pad enabled for SCI is to be in unlocked state=0D + //=0D + if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) =3D=3D Gpio= IntSci) &&=0D + ((GpioData->GpioConfig.LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_= LOCK_MASK) !=3D GpioPadConfigUnlock)){=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a used for SCI is not unlocked!= \n", GpioName (GpioData->GpioPad)));=0D + ASSERT (FALSE);=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + DEBUG_CODE_END ();=0D +=0D + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg));=0D + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask));=0D + //=0D + // Get GPIO PADCFG register value from GPIO config data=0D + //=0D + GpioPadCfgRegValueFromGpioConfig (=0D + GpioData->GpioPad,=0D + &GpioData->GpioConfig,=0D + PadCfgDwReg,=0D + PadCfgDwRegMask=0D + );=0D +=0D + //=0D + // Create PADCFG register offset using group and pad number=0D + //=0D + PadCfgReg =3D S_GPIO_PCR_PADCFG * PadNumber + GpioGroupInfo[GroupInd= ex].PadCfgOffset;=0D +=0D + //=0D + // Write PADCFG DW0 register=0D + //=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, PadCfgReg),=0D + ~PadCfgDwRegMask[0],=0D + PadCfgDwReg[0]=0D + );=0D + //=0D + // Write PADCFG DW1 register=0D + //=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x4),=0D + ~PadCfgDwRegMask[1],=0D + PadCfgDwReg[1]=0D + );=0D +=0D + //=0D + // Write PADCFG DW2 register=0D + //=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, PadCfgReg + 0x8),=0D + ~PadCfgDwRegMask[2],=0D + PadCfgDwReg[2]=0D + );=0D +=0D + //=0D + // Get GPIO DW register values from GPIO config data=0D + //=0D + GpioDwRegValueFromGpioConfig (=0D + PadNumber,=0D + &GpioData->GpioConfig,=0D + GroupDwData=0D + );=0D +=0D + //Move to next item=0D + Index++;=0D + }=0D +=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex= ].PadPerGroup); DwNum++) {=0D + //=0D + // Write HOSTSW_OWN registers=0D + //=0D + if (GpioGroupInfo[GroupIndex].HostOwnOffset !=3D NO_REGISTER_FOR_PRO= PERTY) {=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].HostOwnOffse= t + DwNum * 0x4),=0D + ~GroupDwData[DwNum].HostSoftOwnRegMask,=0D + GroupDwData[DwNum].HostSoftOwnReg=0D + );=0D + }=0D +=0D + //=0D + // Write GPI_GPE_EN registers=0D + //=0D + if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset !=3D NO_REGISTER_FOR_PR= OPERTY) {=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].GpiGpeEnOffs= et + DwNum * 0x4),=0D + ~GroupDwData[DwNum].GpiGpeEnRegMask,=0D + GroupDwData[DwNum].GpiGpeEnReg=0D + );=0D + }=0D +=0D + //=0D + // Write GPI_NMI_EN registers=0D + //=0D + if (GpioGroupInfo[GroupIndex].NmiEnOffset !=3D NO_REGISTER_FOR_PROPE= RTY) {=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].NmiEnOffset = + DwNum * 0x4),=0D + ~GroupDwData[DwNum].GpiNmiEnRegMask,=0D + GroupDwData[DwNum].GpiNmiEnReg=0D + );=0D + } else if (GroupDwData[DwNum].GpiNmiEnReg !=3D 0x0) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting = NMI\n", GroupIndex));=0D + ASSERT_EFI_ERROR (EFI_UNSUPPORTED);=0D + }=0D +=0D + //=0D + // Write GPI_SMI_EN registers=0D + //=0D + if (GpioGroupInfo[GroupIndex].SmiEnOffset !=3D NO_REGISTER_FOR_PROPE= RTY) {=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioCom, GpioGroupInfo[GroupIndex].SmiEnOffset = + DwNum * 0x4),=0D + ~GroupDwData[DwNum].GpiSmiEnRegMask,=0D + GroupDwData[DwNum].GpiSmiEnReg=0D + );=0D + } else if (GroupDwData[DwNum].GpiSmiEnReg !=3D 0x0) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting = SMI\n", GroupIndex));=0D + ASSERT_EFI_ERROR (EFI_UNSUPPORTED);=0D + }=0D +=0D + //=0D + // Update Pad Configuration unlock data=0D + //=0D + if (GroupDwData[DwNum].ConfigUnlockMask) {=0D + GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, GroupDwDat= a[DwNum].ConfigUnlockMask);=0D + }=0D +=0D + //=0D + // Update Pad Output unlock data=0D + //=0D + if (GroupDwData[DwNum].OutputUnlockMask) {=0D + GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, GroupDwData[D= wNum].OutputUnlockMask);=0D + }=0D + }=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will clear all status bits of any GPIO interrupts.=0D +=0D + @param[in] none=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioClearAllGpioInterrupts (=0D + VOID=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + GPIO_GROUP GpioGroupLowest;=0D + GPIO_GROUP GpioGroupHighest;=0D + UINT32 GroupIndex;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 DwNum;=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + GpioGroupLowest =3D GpioGetLowestGroup ();=0D + GpioGroupHighest =3D GpioGetHighestGroup ();=0D +=0D + for (Group =3D GpioGroupLowest; Group <=3D GpioGroupHighest; Group++) {= =0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D + //=0D + // Check if group has GPI IS register=0D + //=0D + if (GpioGroupInfo[GroupIndex].GpiIsOffset !=3D NO_REGISTER_FOR_PROPERT= Y) {=0D + //=0D + // Clear all GPI_IS Status bits by writing '1'=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) {=0D + MmioWrite32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupI= nfo[GroupIndex].GpiIsOffset + DwNum * 0x4),=0D + 0xFFFFFFFF=0D + );=0D + }=0D + }=0D +=0D + //=0D + // Check if group has GPI_GPE_STS register=0D + //=0D + if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset !=3D NO_REGISTER_FOR_PRO= PERTY) {=0D + //=0D + // Clear all GPI_GPE_STS Status bits by writing '1'=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) {=0D + MmioWrite32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupI= nfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4),=0D + 0xFFFFFFFF=0D + );=0D + }=0D + }=0D +=0D + //=0D + // Check if group has SMI_STS register=0D + //=0D + if (GpioGroupInfo[GroupIndex].SmiStsOffset !=3D NO_REGISTER_FOR_PROPER= TY) {=0D + //=0D + // Clear all SMI_STS Status bits by writing '1'=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) {=0D + MmioWrite32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupI= nfo[GroupIndex].SmiStsOffset + DwNum * 4),=0D + 0xFFFFFFFF=0D + );=0D + }=0D + }=0D +=0D + //=0D + // Check if group has NMI_STS register=0D + //=0D + if (GpioGroupInfo[GroupIndex].NmiStsOffset !=3D NO_REGISTER_FOR_PROPER= TY) {=0D + //=0D + // Clear all NMI_STS Status bits by writing '1'=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGroupInfo[GroupInd= ex].PadPerGroup); DwNum++) {=0D + MmioWrite32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, GpioGroupI= nfo[GroupIndex].NmiStsOffset + DwNum * 4),=0D + 0xFFFFFFFF=0D + );=0D + }=0D + }=0D +=0D + }=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG = structure.=0D + Structure contains fields that can be used to configure each pad.=0D + Pad not configured using GPIO_INIT_CONFIG will be left with hardware def= ault values.=0D + Separate fields could be set to hardware default if it does not matter, = except=0D + GpioPad and PadMode.=0D + Function will work in most efficient way if pads which belong to the sam= e group are=0D + placed in adjacent records of the table.=0D + Although function can enable pads for Native mode, such programming is d= one=0D + by reference code when enabling related silicon feature.=0D +=0D + @param[in] NumberofItem Number of GPIO pads to be updated= =0D + @param[in] GpioInitTableAddress GPIO initialization table=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioConfigurePads (=0D + IN UINT32 NumberOfItems,=0D + IN GPIO_INIT_CONFIG *GpioInitTableAddress=0D + )=0D +{=0D + EFI_STATUS Status;=0D +=0D + Status =3D GpioConfigurePch (NumberOfItems, GpioInitTableAddress);=0D +=0D + CreateGpioCheckConflictHob (GpioInitTableAddress, NumberOfItems);=0D +=0D + GpioClearAllGpioInterrupts ();=0D + return Status;=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Librar= y/PeiDxeSmmGpioLib/GpioLib.c new file mode 100644 index 0000000000..d6c13fe581 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioLib.c @@ -0,0 +1,2387 @@ +/** @file=0D + This file contains routines for GPIO=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "GpioLibrary.h"=0D +#include =0D +=0D +/**=0D + This procedure will check if GpioGroup argument is correct and=0D + supplied DW reg number can be used for this group to access DW registers= .=0D + Function will check below conditions:=0D + - Valid GpioGroup=0D + - DwNum is has valid value for this group=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum Register number for current group (parameter app= licable in accessing whole register).=0D + For group which has less then 32 pads per group = DwNum must be 0.=0D +=0D + @retval TRUE DW Reg number and GpioGroup is valid=0D + @retval FALSE DW Reg number and GpioGroup is invalid=0D +**/=0D +STATIC=0D +BOOLEAN=0D +GpioIsGroupAndDwNumValid (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + UINT32 GroupIndex;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D +=0D + if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()) = || (GroupIndex >=3D GpioGroupInfoLength)) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within ra= nge of possible groups for this PCH\n", GroupIndex));=0D + goto Error;=0D + }=0D +=0D + //=0D + // Check if DwNum argument does not exceed number of DWord registers=0D + // resulting from available pads for certain group=0D + //=0D + if (DwNum > GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1))= {=0D + goto Error;=0D + }=0D +=0D + return TRUE;=0D +Error:=0D + ASSERT (FALSE);=0D + return FALSE;=0D +}=0D +=0D +//=0D +// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() fu= nctions=0D +//=0D +typedef enum {=0D + GpioHostOwnershipRegister =3D 0,=0D + GpioGpeEnableRegister,=0D + GpioGpeStatusRegister,=0D + GpioSmiEnableRegister,=0D + GpioSmiStatusRegister,=0D + GpioNmiEnableRegister,=0D + GpioPadConfigLockRegister,=0D + GpioPadLockOutputRegister=0D +} GPIO_REG;=0D +=0D +/**=0D + This procedure will read GPIO register=0D +=0D + @param[in] RegType GPIO register type=0D + @param[in] Group GPIO group=0D + @param[in] DwNum Register number for current group (param= eter applicable in accessing whole register).=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[out] ReadVal Read data=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioReadReg (=0D + IN GPIO_REG RegType,=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + OUT UINT32 *ReadVal=0D + )=0D +{=0D + UINT32 RegOffset;=0D + UINT32 GroupIndex;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D +=0D + RegOffset =3D NO_REGISTER_FOR_PROPERTY;=0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + switch (RegType) {=0D + case GpioHostOwnershipRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset;=0D + break;=0D + case GpioGpeEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset;=0D + break;=0D + case GpioGpeStatusRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset;=0D + break;=0D + case GpioSmiEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset;=0D + break;=0D + case GpioSmiStatusRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset;=0D + break;=0D + case GpioNmiEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset;=0D + break;=0D + case GpioPadConfigLockRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset;=0D + break;=0D + case GpioPadLockOutputRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;=0D + break;=0D + default:=0D + break;=0D + }=0D +=0D + //=0D + // Check if selected register exists=0D + //=0D + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // If there are more then 32 pads per group then certain=0D + // group information would be split into more then one DWord register.=0D + //=0D + if ((RegType =3D=3D GpioPadConfigLockRegister) || (RegType =3D=3D GpioPa= dLockOutputRegister)) {=0D + //=0D + // PadConfigLock and OutputLock registers when used for group containi= ng more than 32 pads=0D + // are not placed in a continuous way, e.g:=0D + // 0x0 - PadConfigLock_DW0=0D + // 0x4 - OutputLock_DW0=0D + // 0x8 - PadConfigLock_DW1=0D + // 0xC - OutputLock_DW1=0D + //=0D + RegOffset +=3D DwNum * 0x8;=0D + } else {=0D + RegOffset +=3D DwNum * 0x4;=0D + }=0D +=0D + *ReadVal =3D MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Comm= unity, RegOffset));=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will write GPIO register=0D +=0D + @param[in] RegType GPIO register type=0D + @param[in] Group GPIO group=0D + @param[in] DwNum Register number for current group (param= eter applicable in accessing whole register).=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] RegAndMask Mask which will be AND'ed with register = value=0D + @param[in] RegOrMask Mask which will be OR'ed with register v= alue=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioWriteReg (=0D + IN GPIO_REG RegType,=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 RegAndMask,=0D + IN UINT32 RegOrMask=0D + )=0D +{=0D + UINT32 RegOffset;=0D + UINT32 GroupIndex;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 PadCfgLock;=0D + BOOLEAN Lockable;=0D +=0D + Lockable =3D FALSE;=0D + PadCfgLock =3D 0;=0D + RegOffset =3D NO_REGISTER_FOR_PROPERTY;=0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + switch (RegType) {=0D + case GpioHostOwnershipRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset;=0D + break;=0D + case GpioGpeEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeEnOffset;=0D + Lockable =3D TRUE;=0D + break;=0D + case GpioGpeStatusRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].GpiGpeStsOffset;=0D + break;=0D + case GpioSmiEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].SmiEnOffset;=0D + Lockable =3D TRUE;=0D + break;=0D + case GpioSmiStatusRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset;=0D + break;=0D + case GpioNmiEnableRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].NmiEnOffset;=0D + Lockable =3D TRUE;=0D + break;=0D + case GpioPadConfigLockRegister:=0D + case GpioPadLockOutputRegister:=0D + default:=0D + break;=0D + }=0D +=0D + //=0D + // Check if selected register exists=0D + //=0D + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (Lockable) {=0D + GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock);=0D + if (PadCfgLock) {=0D + //=0D + // Check if for pads which are going to be reconfigured lock is set.= =0D + //=0D + if ((~RegAndMask | RegOrMask) & PadCfgLock) {=0D + //=0D + // Unlock all pads for this Group DW reg for simplicity=0D + // even if not all of those pads will have their settings reprogra= mmed=0D + //=0D + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock);=0D + } else {=0D + //=0D + // No need to perform an unlock as pads which are going to be reco= nfigured=0D + // are not in locked state=0D + //=0D + PadCfgLock =3D 0;=0D + }=0D + }=0D + }=0D +=0D + //=0D + // If there are more then 32 pads per group then certain=0D + // group information would be split into more then one DWord register.=0D + //=0D + RegOffset +=3D DwNum * 0x4;=0D +=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, RegOffset),=0D + RegAndMask,=0D + RegOrMask=0D + );=0D +=0D + if (Lockable && PadCfgLock) {=0D + //=0D + // Lock previously unlocked pads=0D + //=0D + GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock);=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will write GPIO Lock/LockTx register using SBI.=0D +=0D + @param[in] RegType GPIO register (Lock or LockTx)=0D + @param[in] Group GPIO group number=0D + @param[in] DwNum Register number for current group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] LockRegAndMask Mask which will be AND'ed with Lock regi= ster value=0D + @param[in] LockRegOrMask Mask which will be Or'ed with Lock regis= ter value=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_UNSUPPORTED Feature is not supported for this group = or pad=0D +**/=0D +STATIC=0D +EFI_STATUS=0D +GpioWriteLockReg (=0D + IN GPIO_REG RegType,=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 LockRegAndMask,=0D + IN UINT32 LockRegOrMask=0D + )=0D +{=0D + UINT8 Response;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 RegOffset;=0D + UINT32 OldLockVal;=0D + UINT32 NewLockVal;=0D + UINT32 GroupIndex;=0D + EFI_STATUS Status;=0D + PCH_SBI_OPCODE Opcode;=0D +=0D + OldLockVal =3D 0;=0D + NewLockVal =3D 0;=0D +=0D + RegOffset =3D NO_REGISTER_FOR_PROPERTY;=0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + switch (RegType) {=0D + case GpioPadConfigLockRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockOffset;=0D + GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal);=0D + break;=0D + case GpioPadLockOutputRegister:=0D + RegOffset =3D GpioGroupInfo[GroupIndex].PadCfgLockTxOffset;=0D + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal);=0D + break;=0D + default:=0D + break;=0D + }=0D +=0D + //=0D + // Check if selected register exists=0D + //=0D + if (RegOffset =3D=3D NO_REGISTER_FOR_PROPERTY) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // If there are more then 32 pads per group then certain=0D + // group information would be split into more then one DWord register.=0D + // PadConfigLock and OutputLock registers when used for group containing= more than 32 pads=0D + // are not placed in a continuous way, e.g:=0D + // 0x0 - PadConfigLock_DW0=0D + // 0x4 - OutputLock_DW0=0D + // 0x8 - PadConfigLock_DW1=0D + // 0xC - OutputLock_DW1=0D + //=0D + RegOffset +=3D DwNum *0x8;=0D +=0D + NewLockVal =3D (OldLockVal & LockRegAndMask) | LockRegOrMask;=0D +=0D + if (IsGpioLockOpcodeSupported ()) {=0D + Opcode =3D GpioLockUnlock;=0D + } else {=0D + Opcode =3D PrivateControlWrite;=0D + }=0D +=0D + Status =3D PchSbiExecutionEx (=0D + GpioGroupInfo[GroupIndex].Community,=0D + RegOffset,=0D + Opcode,=0D + FALSE,=0D + 0x000F,=0D + 0x0000,=0D + 0x0000,=0D + &NewLockVal,=0D + &Response=0D + );=0D + ASSERT_EFI_ERROR (Status);=0D + return Status;=0D +}=0D +=0D +/**=0D + This internal procedure will calculate GPIO_RESET_CONFIG value (new typ= e)=0D + based on provided PadRstCfg for a specific GPIO Pad.=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] PadRstCfg GPIO PadRstCfg value=0D +=0D + @retval GpioResetConfig GPIO Reset configuration (new type)=0D +**/=0D +GPIO_RESET_CONFIG=0D +GpioResetConfigFromPadRstCfg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT32 PadRstCfg=0D + )=0D +{=0D + GPIO_GROUP Group;=0D +=0D + static GPIO_RESET_CONFIG PadRstCfgToGpioResetConfigMap[] =3D {=0D + GpioDswReset,=0D + GpioHostDeepReset,=0D + GpioPlatformReset,=0D + GpioResumeReset};=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D +=0D + if (PadRstCfg < 4) {=0D + if (!GpioIsDswGroup(Group) && PadRstCfg =3D=3D 3) {=0D + DEBUG ((DEBUG_ERROR, "ERROR: Pad %a is configured to be reset by Glo= bal Reset without being part of DSW group\n", GpioName (GpioPad)));=0D + }=0D + return PadRstCfgToGpioResetConfigMap[PadRstCfg];=0D + }=0D + return GpioResetDefault;=0D +}=0D +=0D +/**=0D + This internal procedure will calculate PadRstCfg register value based=0D + on provided GPIO Reset configuration for a certain pad.=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] GpioResetConfig GPIO Reset configuration=0D + @param[out] PadRstCfg GPIO PadRstCfg value=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid configuration=0D +**/=0D +EFI_STATUS=0D +GpioPadRstCfgFromResetConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_RESET_CONFIG GpioResetConfig,=0D + OUT UINT32 *PadRstCfg=0D + )=0D +{=0D + GPIO_GROUP Group;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D +=0D + switch (GpioResetConfig) {=0D + case GpioResetDefault:=0D + *PadRstCfg =3D 0x0;=0D + break;=0D + case GpioHostDeepReset:=0D + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_DEEP_RST;=0D + break;=0D + case GpioPlatformReset:=0D + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_GPIO_RST;=0D + break;=0D + case GpioResumeReset:=0D + if (GpioIsDswGroup (Group)) {=0D + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_RESUME_RST;=0D + } else {=0D + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD;=0D + }=0D + break;=0D + case GpioDswReset:=0D + if (GpioIsDswGroup (Group)) {=0D + *PadRstCfg =3D V_GPIO_PCR_RST_CONF_POW_GOOD;=0D + } else {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Only GPD group pads can use Gpio= DswReset: %a\n", GpioName (GpioPad)));=0D + goto Error;=0D + }=0D + break;=0D + default:=0D + goto Error;=0D + }=0D +=0D + return EFI_SUCCESS;=0D +Error:=0D + ASSERT (FALSE);=0D + return EFI_INVALID_PARAMETER;=0D +}=0D +=0D +/**=0D + This internal procedure will get GPIO_CONFIG data from PADCFG registers = value=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] PadCfgDwReg PADCFG DWx register values=0D + @param[out] GpioData GPIO Configuration data=0D +=0D + @retval Status=0D +**/=0D +STATIC=0D +VOID=0D +GpioConfigFromPadCfgRegValue (=0D + IN GPIO_PAD GpioPad,=0D + IN CONST UINT32 *PadCfgDwReg,=0D + OUT GPIO_CONFIG *GpioConfig=0D + )=0D +{=0D + UINT32 PadRstCfg;=0D +=0D + //=0D + // Get Reset Type (PadRstCfg)=0D + //=0D + PadRstCfg =3D (PadCfgDwReg[0] & B_GPIO_PCR_RST_CONF) >> N_GPIO_PCR_RST_C= ONF;=0D +=0D + GpioConfig->PowerConfig =3D GpioResetConfigFromPadRstCfg (=0D + GpioPad,=0D + PadRstCfg=0D + );=0D +=0D + //=0D + // Get how interrupt is triggered (RxEvCfg)=0D + //=0D + GpioConfig->InterruptConfig =3D ((PadCfgDwReg[0] & B_GPIO_PCR_RX_LVL_EDG= ) >> (N_GPIO_PCR_RX_LVL_EDG - (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1))) | = (0x1 << N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS);=0D +=0D + //=0D + // Get interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)=0D + //=0D + GpioConfig->InterruptConfig |=3D ((PadCfgDwReg[0] & (B_GPIO_PCR_RX_NMI_R= OUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_AP= IC_ROUTE)) >> (N_GPIO_PCR_RX_NMI_ROUTE - (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_= POS + 1))) | (0x1 << N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS);=0D +=0D + //=0D + // Get GPIO direction (GPIORxDis and GPIOTxDis)=0D + //=0D + GpioConfig->Direction =3D ((PadCfgDwReg[0] & (B_GPIO_PCR_RXDIS | B_GPIO_= PCR_TXDIS)) >> (N_GPIO_PCR_TXDIS - (N_GPIO_DIRECTION_DIR_BIT_POS + 1))) | (= 0x1 << N_GPIO_DIRECTION_DIR_BIT_POS);=0D +=0D + //=0D + // Get GPIO input inversion (RXINV)=0D + // (Only meaningful if input enabled)=0D + //=0D + if((PadCfgDwReg[0] & B_GPIO_PCR_RXDIS) =3D=3D 0) {=0D + GpioConfig->Direction |=3D ((PadCfgDwReg[0] & B_GPIO_PCR_RXINV) >> (N_= GPIO_PCR_RXINV - (N_GPIO_DIRECTION_INV_BIT_POS + 1))) | (0x1 << N_GPIO_DIRE= CTION_INV_BIT_POS);=0D + }=0D +=0D + //=0D + // Get GPIO output state (GPIOTxState)=0D + //=0D + GpioConfig->OutputState =3D ((PadCfgDwReg[0] & B_GPIO_PCR_TX_STATE) << (= N_GPIO_PCR_TX_STATE + (N_GPIO_OUTPUT_BIT_POS + 1))) | (0x1 << N_GPIO_OUTPUT= _BIT_POS);=0D +=0D + //=0D + // Configure GPIO RX raw override to '1' (RXRAW1)=0D + //=0D + GpioConfig->OtherSettings =3D ((PadCfgDwReg[0] & B_GPIO_PCR_RX_RAW1) >> = (N_GPIO_PCR_RX_RAW1 - (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1))) | (0x1 << N= _GPIO_OTHER_CONFIG_RXRAW_BIT_POS);=0D +=0D + //=0D + // Get GPIO Pad Mode (PMode)=0D + //=0D + GpioConfig->PadMode =3D ((PadCfgDwReg[0] & B_GPIO_PCR_PAD_MODE) >> (N_GP= IO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPIO_PAD_MODE= _BIT_POS);=0D +=0D + //=0D + // Get GPIO termination (Term)=0D + //=0D + GpioConfig->ElectricalConfig =3D ((PadCfgDwReg[1] & B_GPIO_PCR_TERM) >> = (N_GPIO_PCR_TERM - (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1))) | (= 0x1 << N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS);=0D +}=0D +=0D +/**=0D + This procedure will read multiple GPIO settings=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[out] GpioData GPIO data structure=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetPadConfig (=0D + IN GPIO_PAD GpioPad,=0D + OUT GPIO_CONFIG *GpioData=0D + )=0D +{=0D + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];=0D + UINT32 RegVal;=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 PadBitPosition;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Read PADCFG DW0 register=0D + //=0D + PadCfgDwReg[0] =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + //=0D + // Read PADCFG DW1 register=0D + //=0D + PadCfgDwReg[1] =3D GpioReadPadCfgReg (GpioPad, 1);=0D +=0D + //=0D + // Read PADCFG DW2 register=0D + //=0D + PadCfgDwReg[2] =3D GpioReadPadCfgReg (GpioPad, 2);=0D +=0D + GpioConfigFromPadCfgRegValue (=0D + GpioPad,=0D + PadCfgDwReg,=0D + GpioData=0D + );=0D +=0D + //=0D + // Read HOSTSW_OWN registers=0D + //=0D + GpioReadReg (=0D + GpioHostOwnershipRegister,=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &RegVal=0D + );=0D +=0D + //=0D + // Get Host Software Ownership=0D + //=0D + GpioData->HostSoftPadOwn =3D (((RegVal >> PadBitPosition) & 0x1) << (N_G= PIO_HOSTSW_OWN_BIT_POS + 1)) | (0x1 << N_GPIO_HOSTSW_OWN_BIT_POS);=0D +=0D + //=0D + // Read PADCFGLOCK register=0D + //=0D + GpioReadReg (=0D + GpioPadConfigLockRegister,=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &RegVal=0D + );=0D +=0D + //=0D + // Get Pad Configuration Lock state=0D + //=0D + GpioData->LockConfig =3D ((!((RegVal >> PadBitPosition) & 0x1)) << 1) | = BIT0;=0D +=0D + //=0D + // Read PADCFGLOCKTX register=0D + //=0D + GpioReadReg (=0D + GpioPadLockOutputRegister,=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &RegVal=0D + );=0D +=0D + //=0D + // Get Pad Configuration Lock Tx state=0D + //=0D + GpioData->LockConfig |=3D ((!((RegVal >> PadBitPosition) & 0x1)) << 3) |= BIT2;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will calculate PADCFG register value based on GpioConfig = data=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] GpioConfig GPIO Configuration data=0D + @param[out] PadCfgDwReg PADCFG DWx register value=0D + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioPadCfgRegValueFromGpioConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN CONST GPIO_CONFIG *GpioConfig,=0D + OUT UINT32 *PadCfgDwReg,=0D + OUT UINT32 *PadCfgDwRegMask=0D + )=0D +{=0D + UINT32 PadRstCfg;=0D +=0D + //=0D + // Configure Reset Type (PadRstCfg)=0D + // Reset configuration depends on group type.=0D + // This field requires support for new and deprecated settings.=0D + //=0D + GpioPadRstCfgFromResetConfig (=0D + GpioPad,=0D + GpioConfig->PowerConfig,=0D + &PadRstCfg=0D + );=0D +=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PowerConfig & B_GPIO_RESET_CONFI= G_RESET_MASK) >> N_GPIO_RESET_CONFIG_RESET_BIT_POS) =3D=3D GpioHardwareDefa= ult) ? 0x0 : B_GPIO_PCR_RST_CONF);=0D + PadCfgDwReg[0] |=3D PadRstCfg << N_GPIO_PCR_RST_CONF;=0D +=0D + //=0D + // Configure how interrupt is triggered (RxEvCfg)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & B_GPIO_INT_CON= FIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) =3D=3D GpioHardwa= reDefault) ? 0x0 : B_GPIO_PCR_RX_LVL_EDG);=0D + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_I= NT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX= _LVL_EDG);=0D +=0D + //=0D + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->InterruptConfig & B_GPIO_INT_CON= FIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) =3D=3D GpioHa= rdwareDefault) ? 0x0 : (B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE = | B_GPIO_PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE));=0D + PadCfgDwReg[0] |=3D (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_I= NT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PC= R_RX_NMI_ROUTE);=0D +=0D + //=0D + // Configure GPIO direction (GPIORxDis and GPIOTxDis)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & B_GPIO_DIRECTION_DIR= _MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 := (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS));=0D + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK= ) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << N_GPIO_PCR_TXDIS);=0D +=0D + //=0D + // Configure GPIO input inversion (RXINV)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->Direction & B_GPIO_DIRECTION_INV= _MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 = : B_GPIO_PCR_RXINV);=0D + PadCfgDwReg[0] |=3D (((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK= ) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << N_GPIO_PCR_RXINV);=0D +=0D + //=0D + // Configure GPIO output state (GPIOTxState)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK= ) >> N_GPIO_OUTPUT_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_= TX_STATE);=0D + PadCfgDwReg[0] |=3D (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> = (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE);=0D +=0D + //=0D + // Configure GPIO RX raw override to '1' (RXRAW1)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->OtherSettings & B_GPIO_OTHER_CON= FIG_RXRAW_MASK) >> N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) =3D=3D GpioHardwareDe= fault) ? 0x0 : B_GPIO_PCR_RX_RAW1);=0D + PadCfgDwReg[0] |=3D (((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_R= XRAW_MASK) >> (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW= 1);=0D +=0D + //=0D + // Configure GPIO Pad Mode (PMode)=0D + //=0D + PadCfgDwRegMask[0] |=3D ((((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) = >> N_GPIO_PAD_MODE_BIT_POS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_= PAD_MODE);=0D + PadCfgDwReg[0] |=3D (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> (N= _GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE);=0D +=0D + //=0D + // Configure GPIO termination (Term)=0D + //=0D + PadCfgDwRegMask[1] |=3D ((((GpioConfig->ElectricalConfig & B_GPIO_ELECTR= ICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_P= OS) =3D=3D GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM);=0D + PadCfgDwReg[1] |=3D (((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_= CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS += 1)) << N_GPIO_PCR_TERM);=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will configure multiple GPIO settings=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] GpioData GPIO data structure=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetPadConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_CONFIG *GpioData=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER];=0D + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER];=0D + UINT32 HostSoftOwnReg;=0D + UINT32 HostSoftOwnRegMask;=0D + UINT32 GpiGpeEnReg;=0D + UINT32 GpiGpeEnRegMask;=0D + UINT32 GpiNmiEnReg;=0D + UINT32 GpiNmiEnRegMask;=0D + UINT32 GpiSmiEnReg;=0D + UINT32 GpiSmiEnRegMask;=0D + GPIO_GROUP Group;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + UINT32 PadBitPosition;=0D + UINT32 DwNum;=0D + GPIO_LOCK_CONFIG LockConfig;=0D +=0D + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg));=0D + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask));=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Check if Pad enabled for SCI is to be in unlocked state=0D + //=0D + if (((GpioData->InterruptConfig & GpioIntSci) =3D=3D GpioIntSci) &&=0D + ((GpioData->LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) !=3D= GpioPadConfigUnlock)){=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a for SCI is not unlocked!\n", Gpio= Name (GpioPad)));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Get GPIO PADCFG register value from GPIO config data=0D + //=0D + GpioPadCfgRegValueFromGpioConfig (=0D + GpioPad,=0D + GpioData,=0D + PadCfgDwReg,=0D + PadCfgDwRegMask=0D + );=0D +=0D + //=0D + // Write PADCFG DW0 register=0D + //=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + ~PadCfgDwRegMask[0],=0D + PadCfgDwReg[0]=0D + );=0D +=0D + //=0D + // Write PADCFG DW1 register=0D + //=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 1,=0D + ~PadCfgDwRegMask[1],=0D + PadCfgDwReg[1]=0D + );=0D +=0D + //=0D + // Write PADCFG DW2 register=0D + //=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 2,=0D + ~PadCfgDwRegMask[2],=0D + PadCfgDwReg[2]=0D + );=0D +=0D + //=0D + // Update value to be programmed in HOSTSW_OWN register=0D + //=0D + if ((GpioData->InterruptConfig & GpioIntSmi) =3D=3D GpioIntSmi) {=0D + HostSoftOwnRegMask =3D 1 << PadBitPosition;=0D + HostSoftOwnReg =3D 1 << PadBitPosition;=0D + } else {=0D + HostSoftOwnRegMask =3D (GpioData->HostSoftPadOwn & 0x1) << PadBitPosit= ion;=0D + HostSoftOwnReg =3D (GpioData->HostSoftPadOwn >> 0x1) << PadBitPosition= ;=0D + }=0D +=0D + //=0D + // Write HOSTSW_OWN registers=0D + //=0D + GpioWriteReg (=0D + GpioHostOwnershipRegister,=0D + Group,=0D + DwNum,=0D + ~HostSoftOwnRegMask,=0D + HostSoftOwnReg=0D + );=0D +=0D + //=0D + // Update value to be programmed in GPI_GPE_EN register=0D + //=0D + GpiGpeEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPosition;= =0D + GpiGpeEnReg =3D ((GpioData->InterruptConfig & GpioIntSci) >> 3) << PadBi= tPosition;=0D +=0D + //=0D + // Write GPI_GPE_EN registers=0D + //=0D + GpioWriteReg (=0D + GpioGpeEnableRegister,=0D + Group,=0D + DwNum,=0D + ~GpiGpeEnRegMask,=0D + GpiGpeEnReg=0D + );=0D +=0D + //=0D + // Update value to be programmed in GPI_NMI_EN register=0D + //=0D + GpiNmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPosition;= =0D + GpiNmiEnReg =3D ((GpioData->InterruptConfig & GpioIntNmi) >> 1) << PadBi= tPosition;=0D +=0D + Status =3D GpioWriteReg (=0D + GpioNmiEnableRegister,=0D + Group,=0D + DwNum,=0D + ~GpiNmiEnRegMask,=0D + GpiNmiEnReg=0D + );=0D + if (Status =3D=3D EFI_UNSUPPORTED) {=0D + if (GpiNmiEnReg =3D=3D 0) {=0D + //=0D + // Not all GPIO have NMI capabilities. Since we always try to progra= m this register,=0D + // even when not enabling NMI for a pad so do not report such access= as an error=0D + //=0D + Status =3D EFI_SUCCESS;=0D + } else {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting NM= I\n", GpioGetGroupName (GroupIndex)));=0D + ASSERT (FALSE);=0D + return Status;=0D + }=0D + }=0D +=0D + //=0D + // Update value to be programmed in GPI_SMI_EN register=0D + //=0D + GpiSmiEnRegMask =3D (GpioData->InterruptConfig & 0x1) << PadBitPosition;= =0D + GpiSmiEnReg =3D ((GpioData->InterruptConfig & GpioIntSmi) >> 2) << PadBi= tPosition;=0D +=0D + Status =3D GpioWriteReg (=0D + GpioSmiEnableRegister,=0D + Group,=0D + DwNum,=0D + ~GpiSmiEnRegMask,=0D + GpiSmiEnReg=0D + );=0D + if (Status =3D=3D EFI_UNSUPPORTED) {=0D + if (GpiSmiEnReg =3D=3D 0) {=0D + //=0D + // Not all GPIO have SMI capabilities. Since we always try to progra= m this register,=0D + // even when not enabling SMI for a pad so do not report such access= as an error=0D + //=0D + Status =3D EFI_SUCCESS;=0D + } else {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting SM= I\n", GpioGetGroupName (GroupIndex)));=0D + ASSERT (FALSE);=0D + return Status;=0D + }=0D + }=0D +=0D + //=0D + // Store unlock data=0D + //=0D + if (GpioData->LockConfig !=3D GpioLockDefault) {=0D + LockConfig =3D GpioData->LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK= _MASK;=0D + //=0D + // If pad in GpioMode is an output default action should be to leave o= utput unlocked=0D + //=0D + if ((GpioData->PadMode =3D=3D GpioPadModeGpio) &&=0D + (GpioData->Direction =3D=3D GpioDirOut) &&=0D + ((GpioData->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D= GpioLockDefault)) {=0D + LockConfig |=3D GpioOutputStateUnlock;=0D + } else {=0D + LockConfig |=3D GpioData->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOC= K_MASK;=0D + }=0D + Status =3D GpioStoreUnlockData (GpioPad, LockConfig);=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + This procedure will set GPIO output level=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Output value=0D + 0: OutputLow, 1: OutputHigh=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetOutputValue (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT32 Value=0D + )=0D +{=0D + if (Value > 1) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~B_GPIO_PCR_TX_STATE,=0D + Value << N_GPIO_PCR_TX_STATE=0D + );=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO output level=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] OutputVal GPIO Output value=0D + 0: OutputLow, 1: OutputHigh=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetOutputValue (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *OutputVal=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + *OutputVal =3D (PadCfgReg & B_GPIO_PCR_TX_STATE) >> N_GPIO_PCR_TX_STATE;= =0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO input level=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] InputVal GPIO Input value=0D + 0: InputLow, 1: InpuHigh=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetInputValue (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *InputVal=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + *InputVal =3D (PadCfgReg & B_GPIO_PCR_RX_STATE) >> N_GPIO_PCR_RX_STATE;= =0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO IOxAPIC interrupt number=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] IrqNum IRQ number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetPadIoApicIrqNumber (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *IrqNum=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 1);=0D +=0D + *IrqNum =3D (PadCfgReg & B_GPIO_PCR_INTSEL) >> N_GPIO_PCR_INTSEL;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will configure GPIO input inversion=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Value for GPIO input inversion=0D + 0: No input inversion, 1: Invert input=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetInputInversion (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT32 Value=0D + )=0D +{=0D + if (Value > 1) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~B_GPIO_PCR_RXINV,=0D + Value << N_GPIO_PCR_RXINV=0D + );=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO pad input inversion value=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] InvertState GPIO inversion state=0D + 0: No input inversion, 1: Inverted input= =0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetInputInversion (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *InvertState=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgReg =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + *InvertState =3D (PadCfgReg & B_GPIO_PCR_RXINV) >> N_GPIO_PCR_RXINV;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will set GPIO interrupt settings=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Value of Level/Edge=0D + use GPIO_INT_CONFIG as argument=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetPadInterruptConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_INT_CONFIG Value=0D + )=0D +{=0D + EFI_STATUS Status;=0D + UINT32 RxLvlEdgeValue;=0D + UINT32 IntRouteValue;=0D + UINT32 PadNumber;=0D + UINT32 GpeEnable;=0D + UINT32 NmiEnable;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + Status =3D EFI_SUCCESS;=0D +=0D + if (((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_= TYPE_BIT_POS) !=3D GpioHardwareDefault) {=0D + RxLvlEdgeValue =3D ((Value & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> (N_GP= IO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG;=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~B_GPIO_PCR_RX_LVL_EDG,=0D + RxLvlEdgeValue=0D + );=0D + }=0D +=0D + if (((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_IN= T_SOURCE_BIT_POS) !=3D GpioHardwareDefault) {=0D +=0D + IntRouteValue =3D ((Value & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> (N_G= PIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PCR_RX_NMI_ROUTE;=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~(B_GPIO_PCR_RX_NMI_ROUTE | B_GPIO_PCR_RX_SCI_ROUTE | B_GPIO= _PCR_RX_SMI_ROUTE | B_GPIO_PCR_RX_APIC_ROUTE),=0D + IntRouteValue=0D + );=0D +=0D + if ((Value & GpioIntSci) =3D=3D GpioIntSci) {=0D + GpeEnable =3D 0x1;=0D + } else {=0D + GpeEnable =3D 0x0;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioWriteReg (=0D + GpioGpeEnableRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),=0D + GpeEnable << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +=0D + if ((Value & GpioIntNmi) =3D=3D GpioIntNmi) {=0D + NmiEnable =3D 0x1;=0D + } else {=0D + NmiEnable =3D 0x0;=0D + }=0D +=0D + Status =3D GpioWriteReg (=0D + GpioNmiEnableRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + ~(1 << GPIO_GET_PAD_POSITION (PadNumber)),=0D + NmiEnable << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D + if (Status =3D=3D EFI_UNSUPPORTED) {=0D + if (NmiEnable =3D=3D 0) {=0D + //=0D + // Not all GPIO have NMI capabilities. Since we always try to prog= ram this register,=0D + // even when not enabling NMI for a pad so do not report such acce= ss as an error=0D + //=0D + return EFI_SUCCESS;=0D + } else {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %a has no pads supporting = NMI\n", GpioGetGroupName (GpioGetGroupIndexFromGpioPad (GpioPad))));=0D + }=0D + }=0D + ASSERT_EFI_ERROR (Status);=0D + }=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + This procedure will set GPIO electrical settings=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Value of termination=0D + use GPIO_ELECTRICAL_CONFIG as argument=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetPadElectricalConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_ELECTRICAL_CONFIG Value=0D + )=0D +{=0D + UINT32 TermValue;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECT= RICAL_CONFIG_TERMINATION_BIT_POS) !=3D GpioHardwareDefault) {=0D + TermValue =3D ((Value & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> = (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << N_GPIO_PCR_TERM;=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 1,=0D + (UINT32)~B_GPIO_PCR_TERM,=0D + TermValue=0D + );=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will set GPIO Reset settings=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Value for Pad Reset Configuration=0D + use GPIO_RESET_CONFIG as argument=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetPadResetConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_RESET_CONFIG Value=0D + )=0D +{=0D + UINT32 PadRstCfg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (((Value & B_GPIO_RESET_CONFIG_RESET_MASK) >> N_GPIO_RESET_CONFIG_RES= ET_BIT_POS) !=3D GpioHardwareDefault) {=0D +=0D + //=0D + // Reset configuration depends on group type.=0D + // This field requires support for new and deprecated settings.=0D + //=0D + GpioPadRstCfgFromResetConfig (=0D + GpioPad,=0D + Value,=0D + &PadRstCfg=0D + );=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~B_GPIO_PCR_RST_CONF,=0D + PadRstCfg << N_GPIO_PCR_RST_CONF=0D + );=0D + }=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO Reset settings=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] Value Value of Pad Reset Configuration=0D + based on GPIO_RESET_CONFIG=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetPadResetConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_RESET_CONFIG *Value=0D + )=0D +{=0D + UINT32 PadRstCfg;=0D + UINT32 PadCfgDw0Reg;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgDw0Reg =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + //=0D + // Get Reset Type (PadRstCfg)=0D + //=0D + PadRstCfg =3D (PadCfgDw0Reg & B_GPIO_PCR_RST_CONF) >> N_GPIO_PCR_RST_CON= F;=0D +=0D + *Value =3D GpioResetConfigFromPadRstCfg (=0D + GpioPad,=0D + PadRstCfg=0D + );=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +=0D +/**=0D + This procedure will get Gpio Pad Host Software Ownership=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadHostSwOwn Value of Host Software Pad Owner=0D + 0: ACPI Mode, 1: GPIO Driver mode=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetHostSwOwnershipForPad (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *PadHostSwOwn=0D + )=0D +{=0D + UINT32 PadNumber;=0D + UINT32 HostSwRegVal;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioReadReg (=0D + GpioHostOwnershipRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &HostSwRegVal=0D + );=0D +=0D + *PadHostSwOwn =3D (HostSwRegVal >> GPIO_GET_PAD_POSITION (PadNumber)) & = 0x1;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will set Gpio Pad Host Software Ownership=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] PadHostSwOwn Pad Host Software Owner=0D + 0: ACPI Mode, 1: GPIO Driver mode=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioSetHostSwOwnershipForPad (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT32 PadHostSwOwn=0D + )=0D +{=0D + UINT32 PadNumber;=0D +=0D + if (!GpioIsPadValid (GpioPad) || (PadHostSwOwn > 1)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + return GpioWriteReg (=0D + GpioHostOwnershipRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + (UINT32)~(1 << GPIO_GET_PAD_POSITION (PadNumber)),=0D + PadHostSwOwn << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +}=0D +=0D +/**=0D + This procedure will get Gpio Pad Ownership=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadOwnVal Value of Pad Ownership=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetPadOwnership (=0D + IN GPIO_PAD GpioPad,=0D + OUT GPIO_PAD_OWN *PadOwnVal=0D + )=0D +{=0D + UINT32 Mask;=0D + UINT32 RegOffset;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 PadOwnRegValue;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + //=0D + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number.=0D + // One DWord register contains information for 8 pads.=0D + //=0D + RegOffset =3D GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) = * 0x4;=0D +=0D + //=0D + // Calculate pad bit position within DWord register=0D + //=0D + PadNumber %=3D 8;=0D + Mask =3D (BIT1 | BIT0) << (PadNumber * 4);=0D +=0D + PadOwnRegValue =3D MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex= ].Community, RegOffset));=0D +=0D + *PadOwnVal =3D (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> (PadNumber * 4= ));=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will check state of Pad Config Lock for pads within one g= roup=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLock register number for current g= roup.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[out] PadCfgLockRegVal Value of PadCfgLock register=0D + Bit position - PadNumber=0D + Bit value - 0: NotLocked, 1: Locked=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number= =0D +**/=0D +EFI_STATUS=0D +GpioGetPadCfgLockForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + OUT UINT32 *PadCfgLockRegVal=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioReadReg (=0D + GpioPadConfigLockRegister,=0D + Group,=0D + DwNum,=0D + PadCfgLockRegVal=0D + );=0D +}=0D +=0D +/**=0D + This procedure will check state of Pad Config Lock for selected pad=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadCfgLock PadCfgLock for selected pad=0D + 0: NotLocked, 1: Locked=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetPadCfgLock (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *PadCfgLock=0D + )=0D +{=0D + UINT32 PadNumber;=0D + UINT32 PadCfgLockRegVal;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioReadReg (=0D + GpioPadConfigLockRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &PadCfgLockRegVal=0D + );=0D +=0D + *PadCfgLock =3D (PadCfgLockRegVal >> GPIO_GET_PAD_POSITION (PadNumber)) = & 0x1;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will check state of Pad Config Tx Lock for pads within on= e group=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLockTx register number for current= group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[out] PadCfgLockTxRegVal Value of PadCfgLockTx register=0D + Bit position - PadNumber=0D + Bit value - 0: NotLockedTx, 1: LockedTx= =0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number= =0D +**/=0D +EFI_STATUS=0D +GpioGetPadCfgLockTxForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + OUT UINT32 *PadCfgLockTxRegVal=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioReadReg (=0D + GpioPadLockOutputRegister,=0D + Group,=0D + DwNum,=0D + PadCfgLockTxRegVal=0D + );=0D +}=0D +=0D +/**=0D + This procedure will check state of Pad Config Tx Lock for selected pad=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadCfgLock PadCfgLockTx for selected pad=0D + 0: NotLockedTx, 1: LockedTx=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetPadCfgLockTx (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *PadCfgLockTx=0D + )=0D +{=0D + UINT32 PadNumber;=0D + UINT32 PadCfgLockTxRegVal;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioReadReg (=0D + GpioPadLockOutputRegister,=0D + GpioGetGroupFromGpioPad (GpioPad),=0D + GPIO_GET_DW_NUM (PadNumber),=0D + &PadCfgLockTxRegVal=0D + );=0D +=0D + *PadCfgLockTx =3D (PadCfgLockTxRegVal >> GPIO_GET_PAD_POSITION (PadNumbe= r)) & 0x1;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will clear PadCfgLock for selected pads within one group.= =0D + This function should be used only inside SMI.=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLock register number for current g= roup.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToUnlock Bitmask for pads which are going to be u= nlocked,=0D + Bit position - PadNumber=0D + Bit value - 0: DoNotUnlock, 1: Unlock=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioUnlockPadCfgForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 PadsToUnlock=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioWriteLockReg (=0D + GpioPadConfigLockRegister,=0D + Group,=0D + DwNum,=0D + ~PadsToUnlock,=0D + 0=0D + );=0D +}=0D +=0D +/**=0D + This procedure will clear PadCfgLock for selected pad.=0D + This function should be used only inside SMI.=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioUnlockPadCfg (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + return GpioUnlockPadCfgForGroupDw (=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + 1 << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +}=0D +=0D +/**=0D + This procedure will set PadCfgLock for selected pads within one group=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLock register number for current g= roup.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToLock Bitmask for pads which are going to be l= ocked=0D + Bit position - PadNumber=0D + Bit value - 0: DoNotLock, 1: Lock=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number= =0D +**/=0D +EFI_STATUS=0D +GpioLockPadCfgForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 PadsToLock=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioWriteLockReg (=0D + GpioPadConfigLockRegister,=0D + Group,=0D + DwNum,=0D + ~0u,=0D + PadsToLock=0D + );=0D +}=0D +=0D +/**=0D + This procedure will set PadCfgLock for selected pad=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioLockPadCfg (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + return GpioLockPadCfgForGroupDw (=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + 1 << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +}=0D +=0D +/**=0D + This procedure will clear PadCfgLockTx for selected pads within one grou= p.=0D + This function should be used only inside SMI.=0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLockTx register number for current= group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToUnlockTx Bitmask for pads which are going to be u= nlocked,=0D + Bit position - PadNumber=0D + Bit value - 0: DoNotUnLockTx, 1: LockTx= =0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioUnlockPadCfgTxForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 PadsToUnlockTx=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioWriteLockReg (=0D + GpioPadLockOutputRegister,=0D + Group,=0D + DwNum,=0D + ~PadsToUnlockTx,=0D + 0=0D + );=0D +}=0D +=0D +/**=0D + This procedure will clear PadCfgLockTx for selected pad.=0D + This function should be used only inside SMI.=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioUnlockPadCfgTx (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + return GpioUnlockPadCfgTxForGroupDw (=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + 1 << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +}=0D +=0D +/**=0D + This procedure will set PadCfgLockTx for selected pads within one group= =0D +=0D + @param[in] Group GPIO group=0D + @param[in] DwNum PadCfgLock register number for current g= roup.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] PadsToLockTx Bitmask for pads which are going to be l= ocked,=0D + Bit position - PadNumber=0D + Bit value - 0: DoNotLockTx, 1: LockTx=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number= =0D +**/=0D +EFI_STATUS=0D +GpioLockPadCfgTxForGroupDw (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 DwNum,=0D + IN UINT32 PadsToLockTx=0D + )=0D +{=0D + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + return GpioWriteLockReg (=0D + GpioPadLockOutputRegister,=0D + Group,=0D + DwNum,=0D + ~0u,=0D + PadsToLockTx=0D + );=0D +}=0D +=0D +/**=0D + This procedure will set PadCfgLockTx for selected pad=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioLockPadCfgTx (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + return GpioLockPadCfgTxForGroupDw (=0D + Group,=0D + GPIO_GET_DW_NUM (PadNumber),=0D + 1 << GPIO_GET_PAD_POSITION (PadNumber)=0D + );=0D +}=0D +=0D +/**=0D + This procedure will get Group to GPE mapping.=0D + It will assume that only first 32 pads can be mapped to GPE.=0D + To handle cases where groups have more than 32 pads and higher part of g= roup=0D + can be mapped please refer to GpioGetGroupDwToGpeDwX()=0D +=0D + @param[out] GroupToGpeDw0 GPIO group to be mapped to GPE_DW0=0D + @param[out] GroupToGpeDw1 GPIO group to be mapped to GPE_DW1=0D + @param[out] GroupToGpeDw2 GPIO group to be mapped to GPE_DW2=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetGroupToGpeDwX (=0D + IN GPIO_GROUP *GroupToGpeDw0,=0D + IN GPIO_GROUP *GroupToGpeDw1,=0D + IN GPIO_GROUP *GroupToGpeDw2=0D + )=0D +{=0D + UINT32 GroupDw[3];=0D + UINT32 Index;=0D + EFI_STATUS Status;=0D +=0D + Status =3D GpioGetGroupDwToGpeDwX (=0D + GroupToGpeDw0,=0D + &GroupDw[0],=0D + GroupToGpeDw1,=0D + &GroupDw[1],=0D + GroupToGpeDw2,=0D + &GroupDw[2]=0D + );=0D +=0D + for (Index =3D 0; Index < ARRAY_SIZE (GroupDw); Index++) {=0D + if (GroupDw[Index] !=3D 0) {=0D + Status =3D EFI_UNSUPPORTED;=0D + ASSERT (FALSE);=0D + }=0D + }=0D + return Status;=0D +}=0D +=0D +/**=0D + This procedure will get Group to GPE mapping. If group has more than 32 = bits=0D + it is possible to map only single DW of pins (e.g. 0-31, 32-63) because= =0D + ACPI GPE_DWx register is 32 bits large.=0D +=0D + @param[out] GroupToGpeDw0 GPIO group mapped to GPE_DW0=0D + @param[out] GroupDwForGpeDw0 DW of pins mapped to GPE_DW0=0D + @param[out] GroupToGpeDw1 GPIO group mapped to GPE_DW1=0D + @param[out] GroupDwForGpeDw1 DW of pins mapped to GPE_DW1=0D + @param[out] GroupToGpeDw2 GPIO group mapped to GPE_DW2=0D + @param[out] GroupDwForGpeDw2 DW of pins mapped to GPE_DW2=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetGroupDwToGpeDwX (=0D + OUT GPIO_GROUP *GroupToGpeDw0,=0D + OUT UINT32 *GroupDwForGpeDw0,=0D + OUT GPIO_GROUP *GroupToGpeDw1,=0D + OUT UINT32 *GroupDwForGpeDw1,=0D + OUT GPIO_GROUP *GroupToGpeDw2,=0D + OUT UINT32 *GroupDwForGpeDw2=0D + )=0D +{=0D + UINT32 PmcGpeDwXValue[3];=0D + GPIO_GROUP GroupToGpeDwX[3];=0D + UINT32 GroupDwForGpeDwX[3];=0D + UINT8 GpeDwXIndex;=0D + UINT32 Index;=0D + GPIO_GROUP_TO_GPE_MAPPING *GpioGpeMap;=0D + UINT32 GpioGpeMapLength;=0D +=0D + ZeroMem (GroupToGpeDwX, sizeof (GroupToGpeDwX));=0D + ZeroMem (GroupDwForGpeDwX, sizeof (GroupDwForGpeDwX));=0D +=0D + PmcGetGpioGpe (&PmcGpeDwXValue[0], &PmcGpeDwXValue[1], &PmcGpeDwXValue[2= ]);=0D + GpioGetGroupToGpeMapping (&GpioGpeMap, &GpioGpeMapLength);=0D + for (GpeDwXIndex =3D 0; GpeDwXIndex < 3; GpeDwXIndex++) {=0D + for (Index =3D 0; Index < GpioGpeMapLength; Index++) {=0D +=0D + if (GpioGpeMap[Index].PmcGpeDwxVal =3D=3D PmcGpeDwXValue[GpeDwXIndex= ]) {=0D + GroupToGpeDwX[GpeDwXIndex] =3D GpioGpeMap[Index].Group;=0D + GroupDwForGpeDwX[GpeDwXIndex] =3D GpioGpeMap[Index].GroupDw;=0D + break;=0D + }=0D + }=0D + }=0D +=0D + if ((GroupToGpeDwX[0] =3D=3D 0) ||=0D + (GroupToGpeDwX[1] =3D=3D 0) ||=0D + (GroupToGpeDwX[2] =3D=3D 0)) {=0D + ASSERT (FALSE);=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + *GroupToGpeDw0 =3D GroupToGpeDwX[0];=0D + *GroupDwForGpeDw0 =3D GroupDwForGpeDwX[0];=0D + *GroupToGpeDw1 =3D GroupToGpeDwX[1];=0D + *GroupDwForGpeDw1 =3D GroupDwForGpeDwX[1];=0D + *GroupToGpeDw2 =3D GroupToGpeDwX[2];=0D + *GroupDwForGpeDw2 =3D GroupDwForGpeDwX[2];=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPE number for provided GpioPad.=0D + PCH allows to configure mapping between GPIO groups and related GPE (Gpi= oSetGroupToGpeDwX())=0D + what results in the fact that certain Pad can cause different General Pu= rpose Event. Only three=0D + GPIO groups can be mapped to cause unique GPE (1-tier), all others group= s will be under one common=0D + event (GPE_111 for 2-tier).=0D +=0D + 1-tier:=0D + Returned GpeNumber is in range <0,95>. GpioGetGpeNumber() can be used=0D + to determine what _LXX ACPI method would be called on event on selected = GPIO pad=0D +=0D + 2-tier:=0D + Returned GpeNumber is 0x6F (111). All GPIO pads which are not mapped to = 1-tier GPE=0D + will be under one master GPE_111 which is linked to _L6F ACPI method. If= it is needed to determine=0D + what Pad from 2-tier has caused the event, _L6F method should check GPI_= GPE_STS and GPI_GPE_EN=0D + registers for all GPIO groups not mapped to 1-tier GPE.=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] GpeNumber GPE number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetGpeNumber (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINT32 *GpeNumber=0D + )=0D +{=0D + GPIO_GROUP GroupToGpeDwX[3];=0D + UINT32 GroupDw[3];=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 Index;=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Get GPIO groups mapping to 1-tier GPE=0D + // This mapping is dependent on GPIO IP implementation=0D + // and may change between chipset generations=0D + //=0D + GpioGetGroupDwToGpeDwX (=0D + &GroupToGpeDwX[0], &GroupDw[0],=0D + &GroupToGpeDwX[1], &GroupDw[1],=0D + &GroupToGpeDwX[2], &GroupDw[2]=0D + );=0D +=0D + //=0D + // Check if pad is routed to 1-Tier GPE=0D + //=0D + for (Index =3D 0; Index < 3; Index++) {=0D + if ((Group =3D=3D GroupToGpeDwX[Index]) && (PadNumber >=3D (32 * Group= Dw[Index])) && (PadNumber < (32 * (GroupDw[Index] + 1)))) {=0D + *GpeNumber =3D PadNumber + (32 * Index) - (32 * GroupDw[Index]);=0D + return EFI_SUCCESS;=0D + }=0D + }=0D +=0D + //=0D + // If Group number doesn't match any of above then=0D + // it means that the pad is routed to 2-tier GPE=0D + // which corresponds to GPE_111 (0x6F)=0D + //=0D + *GpeNumber =3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure is used to clear SMI STS for a specified Pad=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioClearGpiSmiSts (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 DwNum;=0D + UINT32 PadBitPosition;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D +=0D + //=0D + // Clear GPI SMI Status bit by writing '1'=0D + //=0D + return GpioWriteReg (=0D + GpioSmiStatusRegister,=0D + Group,=0D + DwNum,=0D + 0u,=0D + (UINT32) (BIT0 << PadBitPosition)=0D + );=0D +}=0D +=0D +/**=0D + This procedure is used by PchSmiDispatcher and will clear=0D + all GPI SMI Status bits=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioClearAllGpiSmiSts (=0D + VOID=0D + )=0D +{=0D + UINT32 DwNum;=0D + GPIO_GROUP Group;=0D + GPIO_GROUP GroupMin;=0D + GPIO_GROUP GroupMax;=0D +=0D + GroupMin =3D GpioGetLowestGroup ();=0D + GroupMax =3D GpioGetHighestGroup ();=0D +=0D + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) {=0D + //=0D + // Clear all GPI SMI STS=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup (Grou= p)); DwNum++) {=0D + GpioWriteReg (=0D + GpioSmiStatusRegister,=0D + Group,=0D + DwNum,=0D + 0u,=0D + 0xFFFFFFFF=0D + );=0D + }=0D + }=0D + return EFI_SUCCESS;=0D +=0D +}=0D +=0D +/**=0D + This procedure is used to disable all GPI SMI=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioDisableAllGpiSmi (=0D + VOID=0D + )=0D +{=0D + UINT32 DwNum;=0D + GPIO_GROUP Group;=0D + GPIO_GROUP GroupMin;=0D + GPIO_GROUP GroupMax;=0D + UINT32 SmiEnRegVal;=0D +=0D + GroupMin =3D GpioGetLowestGroup ();=0D + GroupMax =3D GpioGetHighestGroup ();=0D +=0D + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) {=0D + //=0D + // Disable all GPI SMI=0D + //=0D + for (DwNum =3D 0; DwNum <=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup (Grou= p)); DwNum++) {=0D + //=0D + // Check which pins have SMI_EN set=0D + //=0D + GpioReadReg (=0D + GpioSmiEnableRegister,=0D + Group,=0D + DwNum,=0D + &SmiEnRegVal=0D + );=0D + //=0D + // Set HOSTSW_OWN to GPIO mode (1) for those pins to disable SMI cap= ability=0D + //=0D + GpioWriteReg (=0D + GpioHostOwnershipRegister,=0D + Group,=0D + DwNum,=0D + ~0u,=0D + SmiEnRegVal=0D + );=0D + }=0D + }=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure is used to register GPI SMI dispatch function.=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] GpiNum GPI number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetGpiSmiNum (=0D + IN GPIO_PAD GpioPad,=0D + OUT UINTN *GpiNum=0D + )=0D +{=0D + UINT32 GroupIndex;=0D + UINT32 Index;=0D + UINT32 PadNumber;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + *GpiNum =3D 0;=0D +=0D + for (Index =3D 0; Index < GroupIndex; Index++) {=0D + *GpiNum +=3D (UINTN) (GpioGroupInfo[Index].PadPerGroup);=0D + }=0D + *GpiNum +=3D (UINTN) PadNumber;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure is used to check GPIO inputs belongs to 2 tier or 1 tier = architecture=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval Data 0 means 1-tier, 1 means 2-tier=0D +**/=0D +BOOLEAN=0D +GpioCheckFor2Tier (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + UINT32 Data32;=0D +=0D + GpioGetGpeNumber (GpioPad, &Data32);=0D + if (Data32 =3D=3D PCH_GPIO_2_TIER_MASTER_GPE_NUMBER) {=0D + return TRUE;=0D + }=0D +=0D + return FALSE;=0D +}=0D +=0D +/**=0D + This procedure is used to clear GPE STS for a specified GpioPad=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioClearGpiGpeSts (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 DwNum;=0D + UINT32 PadBitPosition;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Check for 2-tier=0D + //=0D + if (!(GpioCheckFor2Tier (GpioPad))) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D +=0D + //=0D + // Clear GPI GPE Status bit by writing '1'=0D + //=0D + return GpioWriteReg (=0D + GpioGpeStatusRegister,=0D + Group,=0D + DwNum,=0D + 0u,=0D + (UINT32) (BIT0 << PadBitPosition)=0D + );=0D +}=0D +=0D +/**=0D + This procedure is used to read GPE STS for a specified Pad=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] GpeSts Gpe status for given pad=0D + The GpeSts is true if the status registe= r is set for given Pad number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetGpiGpeSts (=0D + IN GPIO_PAD GpioPad,=0D + OUT BOOLEAN *GpeSts=0D + )=0D +{=0D + UINT32 GpeStsRegVal;=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 DwNum;=0D + UINT32 PadBitPosition;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + //=0D + // Check for 2-tier=0D + //=0D + if (!(GpioCheckFor2Tier (GpioPad))) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D +=0D + //=0D + // Read GPI GPE Status bits=0D + //=0D + GpioReadReg (=0D + GpioGpeStatusRegister,=0D + Group,=0D + DwNum,=0D + &GpeStsRegVal=0D + );=0D +=0D + *GpeSts =3D ((GpeStsRegVal >> PadBitPosition) & 0x1) !=3D 0;=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure is used to get SMI STS for a specified Pad=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] SmiSts Smi status for given pad=0D + The SmiSts is true if the status registe= r is set for given Pad number=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetGpiSmiSts (=0D + IN GPIO_PAD GpioPad,=0D + OUT BOOLEAN *SmiSts=0D + )=0D +{=0D + GPIO_GROUP Group;=0D + UINT32 PadNumber;=0D + UINT32 DwNum;=0D + UINT32 PadBitPosition;=0D + UINT32 SmiStsRegister;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + Group =3D GpioGetGroupFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + DwNum =3D GPIO_GET_DW_NUM (PadNumber);=0D + PadBitPosition =3D GPIO_GET_PAD_POSITION (PadNumber);=0D +=0D + //=0D + // Read the SMI Register=0D + //=0D + GpioReadReg (=0D + GpioSmiStatusRegister,=0D + Group,=0D + DwNum,=0D + &SmiStsRegister=0D + );=0D +=0D + *SmiSts =3D (SmiStsRegister & (BIT0 << PadBitPosition)) !=3D 0;=0D +=0D + return EFI_SUCCESS;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioLibrary.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Li= brary/PeiDxeSmmGpioLib/GpioLibrary.h new file mode 100644 index 0000000000..d197ee4898 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioLibrary.h @@ -0,0 +1,82 @@ +/** @file=0D + Header file for GPIO Lib implementation.=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#ifndef _GPIO_LIBRARY_H_=0D +#define _GPIO_LIBRARY_H_=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +//=0D +// Number of PADCFG_DW registers=0D +//=0D +#define GPIO_PADCFG_DW_REG_NUMBER 4=0D +=0D +/**=0D + This internal procedure will calculate GPIO_RESET_CONFIG value (new typ= e)=0D + based on provided PadRstCfg for a specific GPIO Pad.=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] PadRstCfg GPIO PadRstCfg value=0D +=0D + @retval GpioResetConfig GPIO Reset configuration (new type)=0D +**/=0D +GPIO_RESET_CONFIG=0D +GpioResetConfigFromPadRstCfg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT32 PadRstCfg=0D + );=0D +=0D +/**=0D + This internal procedure will calculate PadRstCfg register value based=0D + on provided GPIO Reset configuration for a certain pad.=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] GpioResetConfig GPIO Reset configuration=0D + @param[out] PadRstCfg GPIO PadRstCfg value=0D +=0D + @retval EFI_SUCCESS The function completed successfull= y=0D + @retval EFI_INVALID_PARAMETER Invalid configuration=0D +**/=0D +EFI_STATUS=0D +GpioPadRstCfgFromResetConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_RESET_CONFIG GpioResetConfig,=0D + OUT UINT32 *PadRstCfg=0D + );=0D +=0D +/**=0D + This procedure will calculate PADCFG register value based on GpioConfig = data=0D +=0D + @param[in] GpioPad GPIO Pad=0D + @param[in] GpioConfig GPIO Configuration data=0D + @param[out] PadCfgDwReg PADCFG DWx register value=0D + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits= to be modified=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioPadCfgRegValueFromGpioConfig (=0D + IN GPIO_PAD GpioPad,=0D + IN CONST GPIO_CONFIG *GpioConfig,=0D + OUT UINT32 *PadCfgDwReg,=0D + OUT UINT32 *PadCfgDwRegMask=0D + );=0D +=0D +#endif // _GPIO_LIBRARY_H_=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioNames.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Libr= ary/PeiDxeSmmGpioLib/GpioNames.c new file mode 100644 index 0000000000..d21e77ba60 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioNames.c @@ -0,0 +1,86 @@ +/** @file=0D + This file contains GPIO name library implementation=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include "GpioLibrary.h"=0D +#include =0D +=0D +/**=0D + Generates GPIO group name from GpioPad=0D +=0D + @param[in] GpioPad GpioPad=0D +=0D + @retval CHAR8* Pointer to the GPIO group name=0D +**/=0D +CONST=0D +CHAR8*=0D +GpioGetGroupName (=0D + IN UINT32 GroupIndex=0D + )=0D +{=0D + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo;=0D +=0D + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex);=0D + if (GroupNameInfo =3D=3D NULL) {=0D + return NULL;=0D + } else {=0D + return GroupNameInfo->GpioGroupPrefix;=0D + }=0D +}=0D +=0D +/**=0D + Generates GPIO name from GpioPad=0D +=0D + @param[in] GpioPad GpioPad=0D + @param[out] GpioNameBuffer Caller allocated buffer of GPIO_NAME_LEN= GTH_MAX size=0D + @param[in] GpioNameBufferSize Size of the buffer=0D +=0D + @retval CHAR8* Pointer to the GPIO name=0D +**/=0D +CHAR8*=0D +GpioGetPadName (=0D + IN GPIO_PAD GpioPad,=0D + OUT CHAR8* GpioNameBuffer,=0D + IN UINT32 GpioNameBufferSize=0D + )=0D +{=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + UINT32 FirstUniquePadNumber;=0D + CONST GPIO_GROUP_NAME_INFO* GroupNameInfo;=0D +=0D + if (GpioNameBuffer =3D=3D NULL) {=0D + ASSERT (FALSE);=0D + return NULL;=0D + }=0D + if ((GpioNameBufferSize < GPIO_NAME_LENGTH_MAX) || !GpioIsPadValid (Gpio= Pad)) {=0D + ASSERT (FALSE);=0D + *GpioNameBuffer =3D 0;=0D + return NULL;=0D + }=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + GroupNameInfo =3D GpioGetGroupNameInfo (GroupIndex);=0D + if (GroupNameInfo =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + FirstUniquePadNumber =3D GpioGetPadNumberFromGpioPad (GroupNameInfo->Fir= stUniqueGpio);=0D + if ((PadNumber < FirstUniquePadNumber) || (GroupNameInfo->GroupUniqueNam= es =3D=3D NULL)) {=0D + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a%d", GpioGe= tGroupName (GroupIndex), PadNumber);=0D + } else {=0D + if ((PadNumber - FirstUniquePadNumber) < GroupNameInfo->UniqueNamesTab= leSize) {=0D + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%a", GroupN= ameInfo->GroupUniqueNames[PadNumber - FirstUniquePadNumber]);=0D + } else {=0D + AsciiSPrint (GpioNameBuffer, GPIO_NAME_LENGTH_MAX, "GPIO_%08X", Gpio= Pad);=0D + ASSERT (FALSE);=0D + }=0D + }=0D +=0D + return GpioNameBuffer;=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/GpioNativeLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/= Library/PeiDxeSmmGpioLib/GpioNativeLib.c new file mode 100644 index 0000000000..97244c665b --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/GpioNativeLib.c @@ -0,0 +1,193 @@ +/** @file=0D + This file contains routines for GPIO native and chipset specific usage=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include "GpioLibrary.h"=0D +=0D +/**=0D + This procedure will get number of pads for certain GPIO group=0D +=0D + @param[in] Group GPIO group number=0D +=0D + @retval Value Pad number for group=0D + If illegal group number then return 0=0D +**/=0D +UINT32=0D +GpioGetPadPerGroup (=0D + IN GPIO_GROUP Group=0D + )=0D +{=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 GroupIndex;=0D + //=0D + // Check if group argument exceeds GPIO GROUP INFO array=0D + //=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D + GroupIndex =3D GpioGetGroupIndexFromGroup (Group);=0D +=0D + if ((UINTN) GroupIndex >=3D GpioGroupInfoLength) {=0D + return 0;=0D + } else {=0D + return GpioGroupInfo[GroupIndex].PadPerGroup;=0D + }=0D +}=0D +=0D +/**=0D + This procedure will get number of groups=0D +=0D + @param[in] none=0D +=0D + @retval Value Group number=0D +**/=0D +UINT32=0D +GpioGetNumberOfGroups (=0D + VOID=0D + )=0D +{=0D + UINT32 GpioGroupInfoLength;=0D +=0D + GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D + return GpioGroupInfoLength;=0D +}=0D +/**=0D + This procedure will get lowest group=0D +=0D + @param[in] none=0D +=0D + @retval Value Lowest Group=0D +**/=0D +GPIO_GROUP=0D +GpioGetLowestGroup (=0D + VOID=0D + )=0D +{=0D + return GpioGetGroupFromGroupIndex (0);=0D +}=0D +/**=0D + This procedure will get highest group=0D +=0D + @param[in] none=0D +=0D + @retval Value Highest Group=0D +**/=0D +GPIO_GROUP=0D +GpioGetHighestGroup (=0D + VOID=0D + )=0D +{=0D + return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1);=0D +}=0D +=0D +/**=0D + This procedure will get group number=0D +=0D + @param[in] GpioPad Gpio Pad=0D +=0D + @retval Value Group number=0D +**/=0D +GPIO_GROUP=0D +GpioGetGroupFromGpioPad (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + return GPIO_GET_GROUP_FROM_PAD (GpioPad);=0D +}=0D +=0D +/**=0D + This procedure will get group index (0 based)=0D +=0D + @param[in] GpioPad Gpio Pad=0D +=0D + @retval Value Group Index=0D +**/=0D +UINT32=0D +GpioGetGroupIndexFromGpioPad (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad);=0D +}=0D +=0D +/**=0D + This procedure will get group index (0 based) from group=0D +=0D + @param[in] GpioGroup Gpio Group=0D +=0D + @retval Value Group Index=0D +**/=0D +UINT32=0D +GpioGetGroupIndexFromGroup (=0D + IN GPIO_GROUP GpioGroup=0D + )=0D +{=0D + return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup);=0D +}=0D +=0D +/**=0D + This procedure will get group from group index (0 based)=0D +=0D + @param[in] GroupIndex Group Index=0D +=0D + @retval GpioGroup Gpio Group=0D +**/=0D +GPIO_GROUP=0D +GpioGetGroupFromGroupIndex (=0D + IN UINT32 GroupIndex=0D + )=0D +{=0D + return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ());=0D +}=0D +=0D +/**=0D + This procedure will get pad number (0 based) from Gpio Pad=0D +=0D + @param[in] GpioPad Gpio Pad=0D +=0D + @retval Value Pad Number=0D +**/=0D +UINT32=0D +GpioGetPadNumberFromGpioPad (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad);=0D +}=0D +/**=0D + This procedure will return GpioPad from Group and PadNumber=0D +=0D + @param[in] Group GPIO group=0D + @param[in] PadNumber GPIO PadNumber=0D +=0D + @retval GpioPad GpioPad=0D +**/=0D +GPIO_PAD=0D +GpioGetGpioPadFromGroupAndPadNumber (=0D + IN GPIO_GROUP Group,=0D + IN UINT32 PadNumber=0D + )=0D +{=0D + return GPIO_PAD_DEF (Group,PadNumber);=0D +}=0D +=0D +/**=0D + This procedure will return GpioPad from GroupIndex and PadNumber=0D +=0D + @param[in] GroupIndex GPIO GroupIndex=0D + @param[in] PadNumber GPIO PadNumber=0D +=0D + @retval GpioPad GpioPad=0D +**/=0D +GPIO_PAD=0D +GpioGetGpioPadFromGroupIndexAndPadNumber (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 PadNumber=0D + )=0D +{=0D + GPIO_GROUP Group;=0D +=0D + Group =3D GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ());=0D + return GPIO_PAD_DEF (Group, PadNumber);=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeS= mmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/= Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf new file mode 100644 index 0000000000..0a888a38ba --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioL= ib/PeiDxeSmmGpioLib.inf @@ -0,0 +1,49 @@ +## @file=0D +# Component description file for the PeiDxeSmmGpioLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiDxeSmmGpioLib=0D +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662BD7B763F2=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D GpioLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D +#=0D +=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +PrintLib=0D +PchCycleDecodingLib=0D +PchSbiAccessLib=0D +PmcPrivateLib=0D +GpioPrivateLib=0D +SataLib=0D +GpioHelpersLib=0D +GpioCheckConflictLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Pcd]=0D +=0D +[Sources]=0D +GpioLib.c=0D +GpioNativeLib.c=0D +GpioInit.c=0D +GpioNames.c=0D +GpioLibrary.h=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/TigerlakeSi= liconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpers= LibNull.c new file mode 100644 index 0000000000..2c7a1987d9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpi= oHelpersLibNull/BaseGpioHelpersLibNull.c @@ -0,0 +1,119 @@ +/** @file=0D + This file contains NULL implementation for GPIO Helpers Lib=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +=0D +/**=0D + This procedure stores GPIO pad unlock information=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] GpioLockConfig GPIO Lock Configuration=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreUnlockData (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_LOCK_CONFIG GpioLockConfig=0D + )=0D +{=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which PadConfig needs t= o be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockPadConfigData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + )=0D +{=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which Output state need= s to be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockOutputData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + )=0D +{=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which PadConfig is su= pposed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockPadConfigMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + return 0;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which Output is suppo= sed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockOutputMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + return 0;=0D +}=0D +=0D +/**=0D + Returns Gpio Override Level1 Information=0D +=0D + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled=0D +**/=0D +BOOLEAN=0D +GpioOverrideLevel1Enabled (=0D + VOID=0D + )=0D +{=0D + return FALSE;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/Tigerlake= SiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpe= rsLibNull.inf new file mode 100644 index 0000000000..756359d1e3 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpi= oHelpersLibNull/BaseGpioHelpersLibNull.inf @@ -0,0 +1,26 @@ +## @file=0D +# Component description file for the NULL GpioHelpersLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D BaseGpioHelpersLib=0D +FILE_GUID =3D AB282608-2A50-4AE3-9242-64064ECF40D4=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D GpioHelpersLib=0D +=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D +BaseGpioHelpersLibNull.c=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= DxeGpioNameBufferLib/DxeGpioNameBufferLib.inf b/Silicon/Intel/TigerlakeSili= conPkg/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/DxeGpioNameBufferLi= b.inf new file mode 100644 index 0000000000..43860b7d20 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpio= NameBufferLib/DxeGpioNameBufferLib.inf @@ -0,0 +1,32 @@ +## @file=0D +# Component description file for the DxeGpioMemLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D DxeGpioNameBufferLib=0D +FILE_GUID =3D 16EC6AA8-81D5-4847-B6CB-662CDAB863F2=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D DXE_DRIVER=0D +LIBRARY_CLASS =3D GpioNameBufferLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D +#=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +GpioNameBufferDxe.c=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= DxeGpioNameBufferLib/GpioNameBufferDxe.c b/Silicon/Intel/TigerlakeSiliconPk= g/IpBlock/Gpio/LibraryPrivate/DxeGpioNameBufferLib/GpioNameBufferDxe.c new file mode 100644 index 0000000000..87dc9a2cd5 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpio= NameBufferLib/GpioNameBufferDxe.c @@ -0,0 +1,19 @@ +/** @file=0D + This file contains implementation of the GpioMemLib for DXE phase=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +=0D +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];=0D +=0D +CHAR8*=0D +GpioGetStaticNameBuffer (=0D + VOID=0D + )=0D +{=0D + return mGpioNameBuffer;=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= DxeGpioPolicyLib/DxeGpioPolicyLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpB= lock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.c new file mode 100644 index 0000000000..e9fe6f04e0 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpio= PolicyLib/DxeGpioPolicyLib.c @@ -0,0 +1,87 @@ +/** @file=0D + This file provides services for Gpio policy function=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + Print GPIO_DXE_CONFIG and serial out.=0D +=0D + @param[in] PchPolicy Pointer to a PCH_POLICY_PROTOCOL=0D +**/=0D +VOID=0D +GpioDxePrintConfig (=0D + IN PCH_POLICY_PROTOCOL *PchPolicy=0D + )=0D +{=0D + EFI_STATUS Status;=0D + GPIO_DXE_CONFIG *GpioDxeConfig;=0D +=0D + Status =3D GetConfigBlock ((VOID *) PchPolicy, &gGpioDxeConfigGuid, (VOI= D *) &GpioDxeConfig);=0D + ASSERT_EFI_ERROR (Status);=0D +=0D + DEBUG ((DEBUG_INFO, "------------------ GPIO DXE Config ----------------= --\n"));=0D + DEBUG ((DEBUG_INFO, " HideGpioAcpiDevice : %d\n", GpioDxeConfig->HideGpi= oAcpiDevice));=0D +}=0D +=0D +/**=0D + Load DXE Config block default for GPIO=0D +=0D + @param[in] ConfigBlockPointer Pointer to config block=0D +**/=0D +VOID=0D +GpioDxeLoadConfigDefault (=0D + IN VOID *ConfigBlockPointer=0D + )=0D +{=0D + GPIO_DXE_CONFIG *GpioDxeConfig;=0D + GpioDxeConfig =3D ConfigBlockPointer;=0D +=0D + DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Name =3D %g\n", &Gpio= DxeConfig->Header.GuidHob.Name));=0D + DEBUG ((DEBUG_INFO, "GpioDxeConfig->Header.GuidHob.Header.HobLength =3D = 0x%x\n", GpioDxeConfig->Header.GuidHob.Header.HobLength));=0D +=0D + GpioDxeConfig->HideGpioAcpiDevice =3D 0;=0D +}=0D +=0D +STATIC COMPONENT_BLOCK_ENTRY mGpioBlocks =3D {=0D + &gGpioDxeConfigGuid,=0D + sizeof (GPIO_DXE_CONFIG),=0D + GPIO_DXE_CONFIG_REVISION,=0D + GpioDxeLoadConfigDefault=0D +};=0D +=0D +/**=0D + Get Gpio config block table size.=0D +=0D + @retval Size of config block=0D +**/=0D +UINT16=0D +GpioDxeGetConfigBlockTotalSize (=0D + VOID=0D + )=0D +{=0D + return mGpioBlocks.Size;=0D +}=0D +=0D +/**=0D + Add Gpio ConfigBlock.=0D +=0D + @param[in] ConfigBlockTableAddress The pointer to config block table= =0D +=0D + @retval EFI_SUCCESS The policy default is initialized.= =0D + @retval EFI_OUT_OF_RESOURCES Insufficient resources to create b= uffer=0D +**/=0D +EFI_STATUS=0D +GpioDxeAddConfigBlock (=0D + IN VOID *ConfigBlockTableAddress=0D + )=0D +{=0D + return AddComponentConfigBlocks (ConfigBlockTableAddress, &mGpioBlocks, = 1);=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= DxeGpioPolicyLib/DxeGpioPolicyLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/I= pBlock/Gpio/LibraryPrivate/DxeGpioPolicyLib/DxeGpioPolicyLib.inf new file mode 100644 index 0000000000..1b9d53f40c --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/DxeGpio= PolicyLib/DxeGpioPolicyLib.inf @@ -0,0 +1,31 @@ +## @file=0D +# Component description file for the Gpio policy library=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D DxeGpioPolicyLib=0D +FILE_GUID =3D 2D2B8ECA-E343-4036-A289-3F39545AEA06=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D DxeGpioPolicyLib=0D +=0D +[LibraryClasses]=0D +DebugLib=0D +ConfigBlockLib=0D +SiConfigBlockLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +DxeGpioPolicyLib.c=0D +=0D +[Guids]=0D +gGpioDxeConfigGuid ## CONSUMES=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c b/Silicon/Intel/TigerlakeSiliconPkg= /IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNamesVer2.c new file mode 100644 index 0000000000..4084583122 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioNamesVer2.c @@ -0,0 +1,88 @@ +/** @file=0D + This file contains GPIO name library implementation specific to Ver2=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +STATIC CONST CHAR8* mGpioGppbNames[] =3D {=0D + "GSPI0_CLK_LOOPBK",=0D + "GSPI1_CLK_LOOPBK"=0D +};=0D +=0D +STATIC CONST CHAR8* mGpioGppaNames[] =3D {=0D + "SPI0_CLK_LOOPBK",=0D + "ESPI_CLK_LOOPBK"=0D +};=0D +=0D +STATIC CONST CHAR8* mPchLpGpioGpdNames[] =3D {=0D + "INPUT3VSEL",=0D + "SLP_LANB",=0D + "SLP_SUSB",=0D + "SLP_WAKEB",=0D + "SLP_DRAM_RESETB"=0D +};=0D +=0D +STATIC CONST CHAR8* mPchLpGpioGppdNames[] =3D {=0D + "GSPI2_CLK_LOOPBK"=0D +};=0D +=0D +STATIC CONST CHAR8* mGpioGppfNames[] =3D {=0D + "GPPF_CLK_LOOPBK"=0D +};=0D +=0D +STATIC CONST CHAR8* mGpioGppeNames[] =3D {=0D + "GPPE_CLK_LOOPBK"=0D +};=0D +=0D +=0D +STATIC CONST GPIO_GROUP_NAME_INFO mPchLpGroupDescriptors[] =3D {=0D + GPIO_GROUP_NAME("GPP_B", GPIO_VER2_LP_GSPI0_CLK_LOOPBK, mGpioGppbNames),= =0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME("GPP_A", GPIO_VER2_LP_ESPI_CLK_LOOPBK, mGpioGppaNames),= =0D + GPIO_GROUP_NAME_BASIC("GPP_R"),=0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME("GPD", GPIO_VER2_LP_INPUT3VSEL, mPchLpGpioGpdNames),=0D + GPIO_GROUP_NAME_BASIC("GPP_S"),=0D + GPIO_GROUP_NAME_BASIC("GPP_H"),=0D + GPIO_GROUP_NAME("GPP_D", GPIO_VER2_LP_GSPI2_CLK_LOOPBK, mPchLpGpioGppdNa= mes),=0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME_BASIC("GPP_C"),=0D + GPIO_GROUP_NAME("GPP_F", GPIO_VER2_LP_GPPF_CLK_LOOPBK, mGpioGppfNames),= =0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME("GPP_E", GPIO_VER2_LP_GPPE_CLK_LOOPBK, mGpioGppeNames),= =0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME_BASIC(""),=0D + GPIO_GROUP_NAME_BASIC("")=0D +};=0D +=0D +/**=0D + Returns GPIO_GROUP_NAME_INFO corresponding to the given GpioPad=0D +=0D + @param[in] GroupIndex Group index=0D +=0D + @retval GPIO_GROUP_NAME_INFO* Pointer to the GPIO_GROUP_NAME_INFO=0D + @reval NULL If no group descriptor was found=0D +**/=0D +CONST=0D +GPIO_GROUP_NAME_INFO*=0D +GpioGetGroupNameInfo (=0D + IN UINT32 GroupIndex=0D + )=0D +{=0D + if (GroupIndex < ARRAY_SIZE (mPchLpGroupDescriptors)) {=0D + return &mPchLpGroupDescriptors[GroupIndex];=0D + }=0D +=0D + ASSERT (FALSE);=0D + return NULL;=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPk= g/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c new file mode 100644 index 0000000000..f750d77e9a --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioPrivateLib.c @@ -0,0 +1,395 @@ +/** @file=0D + This file contains GPIO routines for RC usage=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +/**=0D + This procedure is used to check if GpioPad is valid for certain chipset= =0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE This pin is valid on this chipset=0D + FALSE Incorrect pin=0D +**/=0D +BOOLEAN=0D +GpioIsCorrectPadForThisChipset (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + return ((GPIO_GET_CHIPSET_ID (GpioPad) =3D=3D GpioGetThisChipsetId ()) &= &=0D + (GpioGetGroupIndexFromGpioPad (GpioPad) < GpioGetNumberOfGroups (= )));=0D +}=0D +=0D +/**=0D + This procedure is used by PchSmiDispatcher and will return information=0D + needed to register GPI SMI.=0D +=0D + @param[in] Index GPI SMI number=0D + @param[out] GpioPin GPIO pin=0D + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi R= egisters=0D + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN register=0D + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioGetPadAndSmiRegs (=0D + IN UINT32 Index,=0D + OUT GPIO_PAD *GpioPin,=0D + OUT UINT8 *GpiSmiBitOffset,=0D + OUT UINT32 *GpiHostSwOwnRegAddress,=0D + OUT UINT32 *GpiSmiStsRegAddress=0D + )=0D +{=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + GPIO_GROUP GpioGroup;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 SmiStsRegOffset;=0D + UINT32 HostSwOwnRegOffset;=0D + GPIO_PAD_OWN PadOwnVal;=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + PadNumber =3D 0;=0D + GroupIndex =3D 0;=0D + for (GroupIndex =3D 0; GroupIndex < GpioGroupInfoLength; GroupIndex++) {= =0D + PadNumber =3D Index;=0D + if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) {=0D + //=0D + // Found group and pad number=0D + //=0D + break;=0D + }=0D + Index =3D Index - GpioGroupInfo[GroupIndex].PadPerGroup;=0D + }=0D +=0D + //=0D + // Check if legal pad number=0D + //=0D + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup){=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + //=0D + // Check if selected group has GPI SMI Enable and Status registers=0D + //=0D + if (GpioGroupInfo[GroupIndex].SmiEnOffset =3D=3D NO_REGISTER_FOR_PROPERT= Y) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + GpioGroup =3D GpioGetGroupFromGroupIndex (GroupIndex);=0D + *GpioPin =3D GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, PadNumber);= =0D +=0D + DEBUG_CODE_BEGIN ();=0D + //=0D + // Check if selected GPIO Pad is not owned by CSME/ISH/IE=0D + //=0D + GpioGetPadOwnership (*GpioPin, &PadOwnVal);=0D + if (PadOwnVal !=3D GpioPadOwnHost) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a not owned by host!\n", GpioName (= *GpioPin)));=0D + return EFI_INVALID_PARAMETER;=0D + }=0D + DEBUG_CODE_END ();=0D +=0D + *GpiSmiBitOffset =3D (UINT8)(PadNumber % 32);=0D +=0D + HostSwOwnRegOffset =3D GpioGroupInfo[GroupIndex].HostOwnOffset + (PadNum= ber / 32) * 0x4;=0D + *GpiHostSwOwnRegAddress =3D PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].C= ommunity, HostSwOwnRegOffset);=0D +=0D + SmiStsRegOffset =3D GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumber = / 32) * 0x4;=0D + *GpiSmiStsRegAddress =3D PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Comm= unity, SmiStsRegOffset);=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will check if GpioPad is owned by host.=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE GPIO pad is owned by host=0D + @retval FALSE GPIO pad is not owned by host and should not be= used with GPIO lib API=0D +**/=0D +BOOLEAN=0D +GpioIsPadHostOwned (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + GPIO_PAD_OWN PadOwnVal;=0D +=0D + //=0D + // Check if selected GPIO Pad is not owned by CSME/ISH=0D + // If GPIO is not owned by Host all access to PadCfg will be dropped=0D + //=0D + GpioGetPadOwnership (GpioPad, &PadOwnVal);=0D + if (PadOwnVal !=3D GpioPadOwnHost) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: %a is not owned by host!\n", GpioNam= e (GpioPad)));=0D + return FALSE;=0D + }=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + This procedure will check if GpioPad argument is valid.=0D + Function will check below conditions:=0D + - GpioPad represents a pad for current PCH=0D + - GpioPad belongs to valid GpioGroup=0D + - GPIO PadNumber is not greater than number of pads for this group=0D +=0D + @param[in] GpioPad GPIO pad=0D +=0D + @retval TRUE GPIO pad is valid and can be used with GPIO lib= API=0D + @retval FALSE GPIO pad is invalid and cannot be used with GPI= O lib API=0D +**/=0D +BOOLEAN=0D +GpioIsPadValid (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 PadNumber;=0D + UINT32 GroupIndex;=0D +=0D + if (!GpioIsCorrectPadForThisChipset (GpioPad)) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on t= his chipset!\n", GpioPad));=0D + goto Error;=0D + }=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + //=0D + // Check if legal pin number=0D + //=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + if (PadNumber >=3D GpioGroupInfo[GroupIndex].PadPerGroup) {=0D + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range of %a = group (max: %d)\n",=0D + = PadNumber,=0D + = GpioGetGroupName (GroupIndex),=0D + = GpioGroupInfo[GroupIndex].PadPerGroup));=0D + goto Error;=0D + }=0D +=0D + return TRUE;=0D +Error:=0D + ASSERT (FALSE);=0D + return FALSE;=0D +}=0D +=0D +/**=0D + This procedure will read GPIO Pad Configuration register=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1=0D +=0D + @retval PadCfgRegValue PADCFG_DWx value=0D +**/=0D +UINT32=0D +GpioReadPadCfgReg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT8 DwReg=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + //=0D + // Create Pad Configuration register offset=0D + //=0D + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG= * PadNumber + 0x4 * DwReg;=0D +=0D + return MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community,= PadCfgReg));=0D +}=0D +=0D +/**=0D + This procedure will write or read GPIO Pad Configuration register=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1=0D + @param[in] PadCfgAndMask Mask to be AND'ed with PADCFG reg value= =0D + @param[in] PadCfgOrMask Mask to be OR'ed with PADCFG reg value=0D +=0D + @retval none=0D +**/=0D +VOID=0D +GpioWritePadCfgReg (=0D + IN GPIO_PAD GpioPad,=0D + IN UINT8 DwReg,=0D + IN UINT32 PadCfgAndMask,=0D + IN UINT32 PadCfgOrMask=0D + )=0D +{=0D + UINT32 PadCfgReg;=0D + CONST GPIO_GROUP_INFO *GpioGroupInfo;=0D + UINT32 GpioGroupInfoLength;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + UINT32 PadCfgLock;=0D + UINT32 PadCfgLockTx;=0D +=0D + PadCfgLock =3D 0;=0D + PadCfgLockTx =3D 0;=0D +=0D + //=0D + // Check if Pad Configuration (except output state) is to be changed.=0D + // If AND and OR masks will indicate that configuration fields (other th= an output control)=0D + // are to be modified it means that there is a need to perform an unlock= (if set)=0D + //=0D + if ((~PadCfgAndMask | PadCfgOrMask) & (UINT32)~B_GPIO_PCR_TX_STATE) {=0D + GpioGetPadCfgLock (GpioPad, &PadCfgLock);=0D + if (PadCfgLock) {=0D + GpioUnlockPadCfg (GpioPad);=0D + }=0D + }=0D +=0D + //=0D + // Check if Pad Output state is to be changed=0D + // If AND and OR masks will indicate that output control=0D + // is to be modified it means that there is a need to perform an unlock = (if set)=0D + //=0D + if ((~PadCfgAndMask | PadCfgOrMask) & B_GPIO_PCR_TX_STATE) {=0D + GpioGetPadCfgLockTx (GpioPad, &PadCfgLockTx);=0D + if (PadCfgLockTx) {=0D + GpioUnlockPadCfgTx (GpioPad);=0D + }=0D + }=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D +=0D + GpioGroupInfo =3D GpioGetGroupInfoTable (&GpioGroupInfoLength);=0D +=0D + //=0D + // Create Pad Configuration register offset=0D + //=0D + PadCfgReg =3D GpioGroupInfo[GroupIndex].PadCfgOffset + S_GPIO_PCR_PADCFG= * PadNumber + 0x4 * DwReg;=0D +=0D + MmioAndThenOr32 (=0D + PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, PadCfgReg),=0D + PadCfgAndMask,=0D + PadCfgOrMask=0D + );=0D +=0D + if (PadCfgLock) {=0D + GpioLockPadCfg (GpioPad);=0D + }=0D + if (PadCfgLockTx) {=0D + GpioLockPadCfgTx (GpioPad);=0D + }=0D +}=0D +=0D +/**=0D + This procedure will set GPIO mode=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] PadModeValue GPIO pad mode value=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid group or pad number=0D +**/=0D +EFI_STATUS=0D +GpioSetPadMode (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_PAD_MODE PadModeValue=0D + )=0D +{=0D + UINT32 PadCfgOrMask;=0D +=0D + PadCfgOrMask =3D 0;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + if (PadModeValue !=3D (GPIO_PAD_MODE)GpioHardwareDefault) {=0D +=0D + PadCfgOrMask =3D (((PadModeValue & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PA= D_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE);=0D +=0D + GpioWritePadCfgReg (=0D + GpioPad,=0D + 0,=0D + (UINT32)~B_GPIO_PCR_PAD_MODE,=0D + PadCfgOrMask=0D + );=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO mode=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[out] PadModeValue GPIO pad mode value=0D +=0D + @retval EFI_SUCCESS The function completed successfully=0D + @retval EFI_INVALID_PARAMETER Invalid GpioPad=0D +**/=0D +EFI_STATUS=0D +GpioGetPadMode (=0D + IN GPIO_PAD GpioPad,=0D + OUT GPIO_PAD_MODE *PadModeValue=0D + )=0D +{=0D + UINT32 PadCfgRegValue;=0D +=0D + if (!GpioIsPadValid (GpioPad)) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if (!GpioIsPadHostOwned (GpioPad)) {=0D + return EFI_UNSUPPORTED;=0D + }=0D +=0D + PadCfgRegValue =3D GpioReadPadCfgReg (GpioPad, 0);=0D +=0D + *PadModeValue =3D (GPIO_PAD_MODE)(((PadCfgRegValue & B_GPIO_PCR_PAD_MODE= ) >> (N_GPIO_PCR_PAD_MODE - (N_GPIO_PAD_MODE_BIT_POS + 1))) | (0x1 << N_GPI= O_PAD_MODE_BIT_POS));=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + Generates GPIO name from GpioPad=0D + This function returns pointer to the static buffer=0D +=0D + @param[in] GpioPad GpioPad=0D +=0D + @retval CHAR8* Pointer to the gpio name string=0D +**/=0D +CHAR8*=0D +GpioName (=0D + IN GPIO_PAD GpioPad=0D + )=0D +{=0D + return GpioGetPadName (GpioPad, GpioGetStaticNameBuffer (), GPIO_NAME_LE= NGTH_MAX);=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c b/Silicon/Intel/TigerlakeSilic= onPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer= 2.c new file mode 100644 index 0000000000..9fea5daa28 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/GpioPrivateLibVer2.c @@ -0,0 +1,131 @@ +/** @file=0D + This file contains VER2 specific GPIO information=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] =3D {= =0D + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_B_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= B_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_B_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_B_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_B_PAD_MAX}, //TGL PCH-LP GPP_B=0D + {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_A_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= A_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_A_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_A_PAD_MAX}, //TGL PCH-LP GPP_A=0D + {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_R_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= R_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_R_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_R_PAD_MAX}, //TGL PCH-LP GPP_R=0D + {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPD_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IS, = R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_= GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPD_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFGLOCKTX, = R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPD_PAD_MAX}, //TGL PCH-LP GPD=0D + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_S_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= S_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_S_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_S_PAD_MAX}, //TGL PCH-LP GPP_S=0D + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_H_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= H_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_H_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_H_PAD_MAX}, //TGL PCH-LP GPP_H=0D + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_D_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= D_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_D_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_D_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_D_PAD_MAX}, //TGL PCH-LP GPP_D=0D + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_C_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= C_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_C_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_C_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_C_PAD_MAX}, //TGL PCH-LP GPP_C=0D + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_F_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= F_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_GPI_GPE_EN, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, R_GPIO_VER2_PCH_LP= _GPIO_PCR_GPP_F_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFGLOCKTX= , R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PADCFG_OFFSET, GPIO_VER2_PCH_LP_GPIO= _GPP_F_PAD_MAX}, //TGL PCH-LP GPP_F=0D + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, R_GPIO_VER2_P= CH_LP_GPIO_PCR_GPP_E_HOSTSW_OWN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IS,= R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_IE, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_= E_GPI_GPE_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_GPI_GPE_EN, R_GPIO_VER2_PC= H_LP_GPIO_PCR_GPP_E_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_GP= IO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NM= I_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPI= O_PCR_GPP_E_PADCFGLOCKTX, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFG_OFFSET= , GPIO_VER2_PCH_LP_GPIO_GPP_E_PAD_MAX}, //TGL PCH-LP GPP_E=0D + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0},=0D + {PID_GPIOCOM3, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_F= OR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FO= R_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_= PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PR= OPERTY, NO_REGISTER_FOR_PROPERTY, = NO_REGISTER_FOR_PROPERTY, 0}=0D +};=0D +=0D +/**=0D + This procedure will retrieve address and length of GPIO info table=0D +=0D + @param[out] GpioGroupInfoTableLength Length of GPIO group table=0D +=0D + @retval Pointer to GPIO group table=0D +=0D +**/=0D +CONST GPIO_GROUP_INFO*=0D +GpioGetGroupInfoTable (=0D + OUT UINT32 *GpioGroupInfoTableLength=0D + )=0D +{=0D + *GpioGroupInfoTableLength =3D ARRAY_SIZE (mPchLpGpioGroupInfo);=0D + return mPchLpGpioGroupInfo;=0D +}=0D +=0D +/**=0D + Get GPIO Chipset ID specific to PCH generation and series=0D +**/=0D +UINT32=0D +GpioGetThisChipsetId (=0D + VOID=0D + )=0D +{=0D + return GPIO_VER2_LP_CHIPSET_ID;=0D +}=0D +=0D +/**=0D + This internal procedure will check if group is within DeepSleepWell.=0D +=0D + @param[in] Group GPIO Group=0D +=0D + @retval GroupWell TRUE: This is DSW Group=0D + FALSE: This is not DSW Group=0D +**/=0D +BOOLEAN=0D +GpioIsDswGroup (=0D + IN GPIO_GROUP Group=0D + )=0D +{=0D + if (Group =3D=3D GPIO_VER2_LP_GROUP_GPD) {=0D + return TRUE;=0D + } else {=0D + return FALSE;=0D + }=0D +}=0D +=0D +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_TO_GPE_MAPPING mPchLpGpioGroupToG= peMapping[] =3D {=0D + {GPIO_VER2_LP_GROUP_GPP_B, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B},= =0D + {GPIO_VER2_LP_GROUP_GPP_A, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A},= =0D + {GPIO_VER2_LP_GROUP_GPP_R, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_R},= =0D + {GPIO_VER2_LP_GROUP_GPD, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD },= =0D + {GPIO_VER2_LP_GROUP_GPP_S, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_S},= =0D + {GPIO_VER2_LP_GROUP_GPP_H, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H},= =0D + {GPIO_VER2_LP_GROUP_GPP_D, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D},= =0D + {GPIO_VER2_LP_GROUP_GPP_C, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C},= =0D + {GPIO_VER2_LP_GROUP_GPP_F, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F},= =0D + {GPIO_VER2_LP_GROUP_GPP_E, 0, V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E}= =0D +};=0D +=0D +/**=0D + Get information for GPIO Group required to program GPIO and PMC for desi= red 1-Tier GPE mapping=0D +=0D + @param[out] GpioGroupToGpeMapping Table with GPIO Group to GPE ma= pping=0D + @param[out] GpioGroupToGpeMappingLength GPIO Group to GPE mapping table= length=0D +**/=0D +VOID=0D +GpioGetGroupToGpeMapping (=0D + OUT GPIO_GROUP_TO_GPE_MAPPING **GpioGroupToGpeMapping,=0D + OUT UINT32 *GpioGroupToGpeMappingLength=0D + )=0D +{=0D + *GpioGroupToGpeMapping =3D mPchLpGpioGroupToGpeMapping;=0D + *GpioGroupToGpeMappingLength =3D ARRAY_SIZE (mPchLpGpioGroupToGpeMapping= );=0D +}=0D +=0D +/**=0D + Check if 0x13 opcode supported for writing to GPIO lock unlock register= =0D +=0D + @retval TRUE It's supported=0D + @retval FALSE It's not supported=0D +**/=0D +BOOLEAN=0D +IsGpioLockOpcodeSupported (=0D + VOID=0D + )=0D +{=0D + return TRUE;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf b/Silicon/Intel/Tig= erlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxe= SmmGpioPrivateLibVer2.inf new file mode 100644 index 0000000000..a355f407f8 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeS= mmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf @@ -0,0 +1,46 @@ +## @file=0D +# Component description file for the PeiDxeSmmGpioPrivateLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiDxeSmmGpioPrivateLibVer2=0D +FILE_GUID =3D 680A81B0-A087-4687-B5B4-146DA30042D6=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D BASE=0D +LIBRARY_CLASS =3D GpioPrivateLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D +#=0D +=0D +=0D +[LibraryClasses]=0D + BaseLib=0D + IoLib=0D + DebugLib=0D + PmcLib=0D + PchInfoLib=0D + GpioLib=0D + GpioNameBufferLib=0D + SataLib=0D + GpioHelpersLib=0D +=0D +=0D +[Packages]=0D + MdePkg/MdePkg.dec=0D + TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D + GpioPrivateLib.c=0D + GpioPrivateLibVer2.c=0D + GpioNamesVer2.c=0D +=0D +[Pcd]=0D +gSiPkgTokenSpaceGuid.PcdEmbeddedEnable ## CONSUME= S=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/TigerlakeSiliconPkg/I= pBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c new file mode 100644 index 0000000000..84bf655ab9 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= HelpersLib/PeiGpioHelpersLib.c @@ -0,0 +1,413 @@ +/** @file=0D + This file contains routines for PEI GPIO Helpers Lib=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +extern EFI_GUID gGpioLibUnlockHobGuid;=0D +=0D +//=0D +// GPIO Lock HOB=0D +// Stores information on GPIO pads that should be left unlocked=0D +//=0D +typedef struct {=0D + //=0D + // GPIO PadConfig unlock data=0D + //=0D + UINT32 PadConfig;=0D + //=0D + // GPIO Output unlock data=0D + //=0D + UINT32 OutputState;=0D +} GPIO_UNLOCK_HOB_DATA;=0D +=0D +/**=0D + This procedure will get index of GPIO Unlock HOB structure for selected = GroupIndex and DwNum.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D +=0D + @retval GpioUnlockHobIndex=0D +**/=0D +STATIC=0D +UINT32=0D +GpioUnlockDataIndex (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + UINT32 GpioUnlockDataIndex;=0D + UINT32 Index;=0D +=0D + GpioUnlockDataIndex =3D 0;=0D +=0D + for (Index =3D 0; Index < GroupIndex; Index++) {=0D + GpioUnlockDataIndex +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup (GpioGetG= roupFromGroupIndex (Index))) + 1;=0D + }=0D +=0D + GpioUnlockDataIndex +=3D DwNum;=0D + return GpioUnlockDataIndex;=0D +}=0D +=0D +/**=0D + This procedure will create GPIO HOB for storing unlock data=0D +=0D + @retval Pointer to GPIO Unlock data structure=0D +**/=0D +STATIC=0D +GPIO_UNLOCK_HOB_DATA*=0D +GpioCreateUnlockData (=0D + VOID=0D + )=0D +{=0D + VOID *HobData;=0D + GPIO_GROUP Group;=0D + GPIO_GROUP GroupMin;=0D + GPIO_GROUP GroupMax;=0D + UINT32 GpioUnlockDataRecords;=0D +=0D + GroupMin =3D GpioGetLowestGroup ();=0D + GroupMax =3D GpioGetHighestGroup ();=0D + GpioUnlockDataRecords =3D 0;=0D +=0D + for (Group =3D GroupMin; Group <=3D GroupMax; Group++) {=0D + GpioUnlockDataRecords +=3D GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)= ) + 1;=0D + }=0D +=0D + HobData =3D BuildGuidHob (&gGpioLibUnlockHobGuid, GpioUnlockDataRecords = * sizeof (GPIO_UNLOCK_HOB_DATA));=0D + if (HobData =3D=3D NULL) {=0D + return NULL;=0D + }=0D +=0D + ZeroMem (HobData, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA))= ;=0D +=0D + return (GPIO_UNLOCK_HOB_DATA*)HobData;=0D +}=0D +=0D +/**=0D + This procedure will Get GPIO Unlock data structure for storing unlock da= ta.=0D + If HOB doesn't exist it will be created.=0D +=0D + @param[out] GpioUnlockData pointer to GPIO Unlock data structur= e=0D +=0D + @retval Length number of GPIO unlock data records=0D +**/=0D +STATIC=0D +UINT32=0D +GpioGetUnlockData (=0D + GPIO_UNLOCK_HOB_DATA **GpioUnlockData=0D + )=0D +{=0D + VOID *Hob;=0D +=0D + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid);=0D + if (Hob =3D=3D NULL) {=0D + //=0D + // It is the first time this function is used so create the HOB=0D + //=0D + *GpioUnlockData =3D GpioCreateUnlockData ();=0D + if (*GpioUnlockData =3D=3D NULL) {=0D + return 0;=0D + }=0D + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid);=0D + } else {=0D + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob);=0D + }=0D + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA);=0D +}=0D +=0D +/**=0D + This procedure will get pointer to GPIO Unlock data structure.=0D +=0D + @param[out] GpioUnlockData pointer to GPIO Unlock data structur= e=0D +=0D + @retval Length number of GPIO unlock data records=0D +**/=0D +STATIC=0D +UINT32=0D +GpioLocateUnlockData (=0D + GPIO_UNLOCK_HOB_DATA **GpioUnlockData=0D + )=0D +{=0D + VOID *Hob;=0D +=0D + Hob =3D GetFirstGuidHob (&gGpioLibUnlockHobGuid);=0D + if (Hob =3D=3D NULL) {=0D + *GpioUnlockData =3D NULL;=0D + return 0;=0D + }=0D +=0D + *GpioUnlockData =3D (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob);=0D + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA);=0D +}=0D +=0D +/**=0D + This procedure stores GPIO pad unlock information=0D +=0D + @param[in] GpioPad GPIO pad=0D + @param[in] GpioLockConfig GPIO Lock Configuration=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreUnlockData (=0D + IN GPIO_PAD GpioPad,=0D + IN GPIO_LOCK_CONFIG GpioLockConfig=0D + )=0D +{=0D + GPIO_UNLOCK_HOB_DATA *GpioUnlockData;=0D + UINT32 Length;=0D + UINT32 GroupIndex;=0D + UINT32 PadNumber;=0D + UINT32 Index;=0D +=0D + if (GpioLockConfig =3D=3D GpioLockDefault) {=0D + return EFI_SUCCESS;=0D + }=0D +=0D + Length =3D GpioGetUnlockData (&GpioUnlockData);=0D + if (Length =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + GroupIndex =3D GpioGetGroupIndexFromGpioPad (GpioPad);=0D + PadNumber =3D GpioGetPadNumberFromGpioPad (GpioPad);=0D + Index =3D GpioUnlockDataIndex (GroupIndex, GPIO_GET_DW_NUM (PadNumber));= =0D +=0D + if (Index >=3D Length) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) =3D=3D Gpio= PadConfigUnlock) {=0D + GpioUnlockData[Index].PadConfig |=3D 1 << (GpioGetPadNumberFromGpioPad= (GpioPad) % 32);=0D + }=0D +=0D + if ((GpioLockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) =3D=3D GpioOu= tputStateUnlock) {=0D + GpioUnlockData[Index].OutputState |=3D 1 << (GpioGetPadNumberFromGpioP= ad (GpioPad) % 32);=0D + }=0D +=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which PadConfig needs t= o be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D +=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockPadConfigData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + )=0D +{=0D + GPIO_UNLOCK_HOB_DATA *GpioUnlockData;=0D + UINT32 Length;=0D + UINT32 Index;=0D +=0D + if (UnlockedPads =3D=3D 0) {=0D + //=0D + // No pads to be left unlocked=0D + //=0D + return EFI_SUCCESS;=0D + }=0D +=0D + Length =3D GpioGetUnlockData (&GpioUnlockData);=0D + if (Length =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum);=0D + if (Index >=3D Length) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + GpioUnlockData[Index].PadConfig |=3D UnlockedPads;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure stores GPIO group data about pads which Output state need= s to be unlocked.=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @param[in] UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: Skip, 1: Leave unlocked=0D + @retval Status=0D +**/=0D +EFI_STATUS=0D +GpioStoreGroupDwUnlockOutputData (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum,=0D + IN UINT32 UnlockedPads=0D + )=0D +{=0D + GPIO_UNLOCK_HOB_DATA *GpioUnlockData;=0D + UINT32 Length;=0D + UINT32 Index;=0D +=0D + if (UnlockedPads =3D=3D 0) {=0D + //=0D + // No pads to be left unlocked=0D + //=0D + return EFI_SUCCESS;=0D + }=0D +=0D + Length =3D GpioGetUnlockData (&GpioUnlockData);=0D + if (Length =3D=3D 0) {=0D + return EFI_NOT_FOUND;=0D + }=0D +=0D + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum);=0D + if (Index >=3D Length) {=0D + return EFI_INVALID_PARAMETER;=0D + }=0D +=0D + GpioUnlockData[Index].OutputState |=3D UnlockedPads;=0D + return EFI_SUCCESS;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which PadConfig is su= pposed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockPadConfigMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + GPIO_UNLOCK_HOB_DATA *GpioUnlockData;=0D + UINT32 Length;=0D + UINT32 Index;=0D +=0D + Length =3D GpioLocateUnlockData (&GpioUnlockData);=0D + if (Length =3D=3D 0) {=0D + return 0;=0D + }=0D +=0D + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum);=0D + if (Index >=3D Length) {=0D + return 0;=0D + }=0D +=0D + return GpioUnlockData[Index].PadConfig;=0D +}=0D +=0D +/**=0D + This procedure will get GPIO group data with pads, which Output is suppo= sed to be left unlock=0D +=0D + @param[in] GroupIndex GPIO group index=0D + @param[in] DwNum DWORD index for a group.=0D + For group which has less then 32 pads pe= r group DwNum must be 0.=0D + @retval UnlockedPads DWORD bitmask for pads which are going t= o be left unlocked=0D + Bit position - PadNumber=0D + Bit value - 0: to be locked, 1: Leave un= locked=0D +**/=0D +UINT32=0D +GpioGetGroupDwUnlockOutputMask (=0D + IN UINT32 GroupIndex,=0D + IN UINT32 DwNum=0D + )=0D +{=0D + GPIO_UNLOCK_HOB_DATA *GpioUnlockData;=0D + UINT32 Length;=0D + UINT32 Index;=0D +=0D + Length =3D GpioLocateUnlockData (&GpioUnlockData);=0D + if (Length =3D=3D 0) {=0D + return 0;=0D + }=0D +=0D + Index =3D GpioUnlockDataIndex (GroupIndex, DwNum);=0D + if (Index >=3D Length) {=0D + return 0;=0D + }=0D +=0D + return GpioUnlockData[Index].OutputState;=0D +}=0D +=0D +/**=0D + Obtains GpioOverride Information from PreMem config=0D +=0D + @retval TRUE GPIO Override obtained successfully=0D + FALSE Unable to obtain GPIO Override data=0D +**/=0D +BOOLEAN=0D +STATIC=0D +GetGpioOverrideFromConfigBlock (=0D + IN OUT UINT8 *GpioOverride=0D + )=0D +{=0D + EFI_STATUS Status;=0D + SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi;=0D + PCH_GENERAL_PREMEM_CONFIG *PchGeneralPreMemConfig;=0D +=0D + Status =3D PeiServicesLocatePpi (=0D + &gSiPreMemPolicyPpiGuid,=0D + 0,=0D + NULL,=0D + (VOID **) &SiPreMemPolicyPpi=0D + );=0D + if (EFI_ERROR (Status)) {=0D + return FALSE;=0D + }=0D + Status =3D GetConfigBlock ((VOID *) SiPreMemPolicyPpi, &gPchGeneralPreMe= mConfigGuid, (VOID *) &PchGeneralPreMemConfig);=0D + if (EFI_ERROR (Status)) {=0D + return FALSE;=0D + }=0D + *GpioOverride =3D (UINT8) PchGeneralPreMemConfig->GpioOverride;=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Returns Gpio Override Level1 Information=0D +=0D + @retval TRUE/FALSE GPIO Override Level 1 Enabled/Disabled=0D +**/=0D +BOOLEAN=0D +GpioOverrideLevel1Enabled (=0D + VOID=0D + )=0D +{=0D + UINT8 GpioOverride;=0D +=0D + GpioOverride =3D 0;=0D +=0D + if (GetGpioOverrideFromConfigBlock (&GpioOverride)) {=0D + if (GpioOverride =3D=3D 1) { return TRUE; }=0D + }=0D +=0D + return FALSE;=0D +}=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/TigerlakeSiliconPkg= /IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf new file mode 100644 index 0000000000..d70c2a1352 --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= HelpersLib/PeiGpioHelpersLib.inf @@ -0,0 +1,48 @@ +## @file=0D +# Component description file for the PeiGpioHelpersLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiGpioHelpersLib=0D +FILE_GUID =3D 1838E1E7-3CC4-4A74-90D9-B421EF2A579F=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D PEIM=0D +LIBRARY_CLASS =3D GpioHelpersLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32 X64 IPF EBC=0D +#=0D +=0D +=0D +[LibraryClasses]=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +HobLib=0D +GpioLib=0D +PeiServicesLib=0D +=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +=0D +[Sources]=0D +PeiGpioHelpersLib.c=0D +=0D +=0D +[Guids]=0D +gGpioLibUnlockHobGuid=0D +gPchGeneralPreMemConfigGuid ## CONSUMES=0D +=0D +[Ppis]=0D +gSiPreMemPolicyPpiGuid=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioNameBufferLib/GpioNameBufferPei.c b/Silicon/Intel/TigerlakeSiliconPk= g/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/GpioNameBufferPei.c new file mode 100644 index 0000000000..920d9a2cbc --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= NameBufferLib/GpioNameBufferPei.c @@ -0,0 +1,67 @@ +/** @file=0D + This file contains GpioMemLib implementation for PEI phase=0D +=0D + Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D + SPDX-License-Identifier: BSD-2-Clause-Patent=0D +**/=0D +=0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +STATIC CONST EFI_GUID mGpioNamesPrivateHobGuid =3D {0x9AE3138D, 0x4EBF, 0x= 4E90, {0x87, 0x96, 0x11, 0xD3, 0x10, 0x04, 0x60, 0x0A}};=0D +=0D +STATIC volatile BOOLEAN mGlobalMemoryWorking =3D FALSE;=0D +=0D +STATIC CHAR8 mGpioNameBuffer[GPIO_NAME_LENGTH_MAX];=0D +=0D +/**=0D + Returns pointer to the buffer taken from GpioLib private HOB=0D +=0D + @retval CHAR8* Pointer to the buffer=0D +**/=0D +STATIC=0D +CHAR8*=0D +GetBufferFromHob (=0D + VOID=0D + )=0D +{=0D + VOID *Hob;=0D + CHAR8 *GpioNameBuffer;=0D +=0D + Hob =3D NULL;=0D + GpioNameBuffer =3D NULL;=0D +=0D + Hob =3D GetFirstGuidHob (&mGpioNamesPrivateHobGuid);=0D + if (Hob !=3D NULL){=0D + GpioNameBuffer =3D (CHAR8*) GET_GUID_HOB_DATA (Hob);=0D + } else {=0D + GpioNameBuffer =3D (CHAR8*) BuildGuidHob (&mGpioNamesPrivateHobGuid, G= PIO_NAME_LENGTH_MAX);=0D + if (GpioNameBuffer =3D=3D NULL){=0D + DEBUG ((DEBUG_ERROR, "Failed to setup HOB for GPIO names lib\n"));=0D + ASSERT (FALSE);=0D + }=0D + }=0D + return GpioNameBuffer;=0D +}=0D +=0D +/**=0D + Returns pointer to the global buffer to be used by GpioNamesLib=0D +=0D + @retval CHAR8* Pointer to the buffer=0D +**/=0D +CHAR8*=0D +GpioGetStaticNameBuffer (=0D + VOID=0D + )=0D +{=0D + mGlobalMemoryWorking =3D TRUE;=0D +=0D + if (mGlobalMemoryWorking) {=0D + return mGpioNameBuffer;=0D + } else {=0D + return GetBufferFromHob ();=0D + }=0D +}=0D +=0D diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/= PeiGpioNameBufferLib/PeiGpioNameBufferLib.inf b/Silicon/Intel/TigerlakeSili= conPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioNameBufferLib/PeiGpioNameBufferLi= b.inf new file mode 100644 index 0000000000..0525a42a8d --- /dev/null +++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpio= NameBufferLib/PeiGpioNameBufferLib.inf @@ -0,0 +1,35 @@ +## @file=0D +# Component description file for the PeiGpioMemLib=0D +#=0D +# Copyright (c) 2021, Intel Corporation. All rights reserved.
=0D +# SPDX-License-Identifier: BSD-2-Clause-Patent=0D +#=0D +##=0D +=0D +=0D +[Defines]=0D +INF_VERSION =3D 0x00010017=0D +BASE_NAME =3D PeiGpioNameBufferLib=0D +FILE_GUID =3D 16EC5CA8-8195-4847-B6CB-662CDAB863F2=0D +VERSION_STRING =3D 1.0=0D +MODULE_TYPE =3D PEIM=0D +LIBRARY_CLASS =3D GpioNameBufferLib=0D +#=0D +# The following information is for reference only and not required by the = build tools.=0D +#=0D +# VALID_ARCHITECTURES =3D IA32=0D +#=0D +=0D +[LibraryClasses]=0D +HobLib=0D +BaseLib=0D +IoLib=0D +DebugLib=0D +=0D +[Packages]=0D +MdePkg/MdePkg.dec=0D +TigerlakeSiliconPkg/SiPkg.dec=0D +=0D +[Sources]=0D +GpioNameBufferPei.c=0D +=0D --=20 2.24.0.windows.2