Adds the following modules: - IpBlock/CpuPcieRp/Include - IpBlock/Espi/Library - IpBlock/Gpio/IncludePrivate - IpBlock/Gpio/Library - IpBlock/Gpio/LibraryPrivate
Cc: Sai Chaganty <rangasai.v.chaga...@intel.com> Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> Cc: Rosen Chuang <rosen.chu...@intel.com> Signed-off-by: Saloni Kasbekar <saloni.kasbe...@intel.com> --- .../IpBlock/CpuPcieRp/Include/CpuPcieInfo.h | 25 + .../Espi/Library/PeiDxeSmmEspiLib/EspiLib.c | 58 ++ .../PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf | 38 ++ .../IncludePrivate/Library/GpioHelpersLib.h | 50 ++ .../IncludePrivate/Library/GpioNativePads.h | 245 ++++++++ .../IncludePrivate/Library/GpioPrivateLib.h | 350 +++++++++++ .../Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c | 546 ++++++++++++++++++ .../Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c | 522 +++++++++++++++++ .../Library/PeiDxeSmmGpioLib/GpioLibrary.h | 29 + .../Library/PeiDxeSmmGpioLib/GpioNativeLib.c | 177 ++++++ .../PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf | 44 ++ .../BaseGpioHelpersLibNull.c | 51 ++ .../BaseGpioHelpersLibNull.inf | 25 + .../GpioNativePrivateLibInternal.h | 48 ++ .../PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c | 267 +++++++++ .../GpioPrivateLibPch.c | 172 ++++++ .../GpioPrivateLibVer2.c | 81 +++ .../PeiDxeSmmGpioPrivateLibVer2.inf | 40 ++ .../PeiGpioHelpersLib/PeiGpioHelpersLib.c | 218 +++++++ .../PeiGpioHelpersLib/PeiGpioHelpersLib.inf | 46 ++ 20 files changed, 3032 insertions(+) create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c create mode 100644 Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h new file mode 100644 index 0000000000..a6f8b16d10 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/CpuPcieRp/Include/CpuPcieInfo.h @@ -0,0 +1,25 @@ +/** @file + This file contains definitions of PCIe controller information + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _CPU_PCIE_INFO_H_ +#define _CPU_PCIE_INFO_H_ + +#define PCIE_HWEQ_COEFFS_MAX 5 + + +// +// SA PCI Express* Port configuration +// + +#define CPU_PCIE_MAX_ROOT_PORTS 4 +#define CPU_PCIE_MAX_CONTROLLERS 3 + +#define SA_PEG_MAX_FUN 0x04 +#define SA_PEG_MAX_LANE 0x14 + + + +#endif diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c new file mode 100644 index 0000000000..2e4d1375ca --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/EspiLib.c @@ -0,0 +1,58 @@ +/** @file + This file contains routines for eSPI + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/EspiLib.h> +#include <Library/PchPcrLib.h> +#include <Library/PchInfoLib.h> +#include <Library/TimerLib.h> +#include <PchLimits.h> +#include <Register/PchPcrRegs.h> +#include <Register/PchRegsLpc.h> + + +/** + Checks if second device capability is enabled + + @retval TRUE There's second device + @retval FALSE There's no second device +**/ +BOOLEAN +IsEspiSecondSlaveSupported ( + VOID + ) +{ + return ((PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_SOFTSTRAPS) & B_ESPI_PCR_SOFTSTRAPS_CS1_EN) != 0); +} + + +/** + Is eSPI enabled in strap. + + @retval TRUE Espi is enabled in strap + @retval FALSE Espi is disabled in strap +**/ +BOOLEAN +IsEspiEnabled ( + VOID + ) +{ + return (PchPcrRead32 (PID_ESPISPI, R_ESPI_PCR_CFG_VAL) & B_ESPI_PCR_CFG_VAL_ESPI_EN) != 0; +} + +typedef enum { + EspiSlaveOperationConfigRead, + EspiSlaveOperationConfigWrite, + EspiSlaveOperationStatusRead, + EspiSlaveOperationInBandReset +} ESPI_SLAVE_OPERATION; + + + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf new file mode 100644 index 0000000000..e8db1e4e8d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Espi/Library/PeiDxeSmmEspiLib/PeiDxeSmmEspiLib.inf @@ -0,0 +1,38 @@ +## @file +# Component description file for the PeiDxeSmmPchEspiLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmEspiLib +FILE_GUID = 7F25F990-7989-4413-B414-1EDE557E9389 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = EspiLib +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PchPcrLib +TimerLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +EspiLib.c diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h new file mode 100644 index 0000000000..cf67c81ed0 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioHelpersLib.h @@ -0,0 +1,50 @@ +/** @file + Header file for GPIO Helpers Lib implementation. + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_HELPERS_LIB_H_ +#define _GPIO_HELPERS_LIB_H_ + +#include <Library/GpioConfig.h> + +/** + This procedure stores GPIO group data about pads which PadConfig needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] PadsToLock DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockPadConfigData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ); + +/** + This procedure stores GPIO group data about pads which Output state needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] PadsToLock DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockOutputData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ); + +#endif // _GPIO_HELPERS_LIB_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h new file mode 100644 index 0000000000..dbd13963fa --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioNativePads.h @@ -0,0 +1,245 @@ +/** @file + Header file for GPIO Native pads support + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_NATIVE_PADS_H_ +#define _GPIO_NATIVE_PADS_H_ + +// +// GpioPad can contain additional information used to provide data on +// native functions. Please refer to description of GPIO_NATIVE_PAD +// +// FFFF CCCC TTTG GGGG TTTT TTTP PPPP PPPP +// +// F - 2^4 = 16, native function number +// C - 2^4 = 16, chipset ID +// T - 2^10 = 1024 , abstract type representing native mode of a pad (e.g. SERIALIO_UART2_TX) +// G - 2^5 = 32, group +// P - 2^9 = 512, pad number +// +// F & T contain additional optional settings used for native pads +// +#define GPIO_NATIVE_PAD_DEF(GpioNativePad, NativeMode, NativeFunction) \ + (GpioNativePad | (NativeMode << 28) | ((NativeFunction & 0x7F) << 9) | ((NativeFunction & 0x380) << 14)) + +#define GPIO_NATIVE_GET_FUNCTION(GpioNativePad) ((((GpioNativePad) & 0xFE00) >> 9) | (((GpioNativePad) & 0xE00000) >> 14)) +#define GPIO_NATIVE_GET_PAD_FN(GpioNativePad) (((GpioNativePad) >> 28) & 0xF) +#define GPIO_NATIVE_GET_PAD_MODE(GpioNativePad) ((GPIO_NATIVE_GET_PAD_FN(GpioNativePad) << 1) | 1) +#define GPIO_NATIVE_TO_GPIO_PAD(GpioNativePad) (GpioNativePad & 0xF1F01FF) + +// +// Below defines and macros are used to build abstract type +// to help encode native pin information in GPIO_PAD +// + +// +// Macro used to define GPIO native function. +// <Min,Max> defines range that can be used to encode given native signal. +// Numbering must be unique and cannot overlap. +// If there are many instances of similar signal (e.g. per controller) the lower +// word will store value for a given instance in the form: Min + Instance +// Upper word (Max) is left untouched and later used for verification +// +#define GPIO_NATIVE_FUNCTION_DEF(Min, Max) (((Max) << 16) + (Min)) +#define GPIO_NATIVE_FUNCTION_GET_MAX(NativeFunction) (((NativeFunction) >> 16) & 0xFFFF) +#define GPIO_NATIVE_FUNCTION_GET_VALUE(NativeFunction) ((NativeFunction) & 0xFFFF) + +// +// Macro GPIO_NATIVE_FUNCTION_GET_SIGNAL is created as synonym to macro GPIO_NATIVE_FUNCTION_GET_MAX +// GPIO_NATIVE_FUNCTION_GET_SIGNAL used with below defines is more descriptive and easier to read +// ex. +// - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_SERIAL_IO_UART_RX) +// - GPIO_NATIVE_FUNCTION_GET_SIGNAL(GPIO_ISH_GP) +// - ... +// +#define GPIO_NATIVE_FUNCTION_GET_SIGNAL(NativeFunction) (GPIO_NATIVE_FUNCTION_GET_MAX(NativeFunction)) + +// +// GPIO native modes +// Those defines are internal to this header. +// GPIO_FUNCTION_<IP>_<signal>(index) defines should be used by other modules instead. +// +#define GPIO_SERIAL_IO_UART_RX GPIO_NATIVE_FUNCTION_DEF(1,8) +#define GPIO_SERIAL_IO_UART_TX GPIO_NATIVE_FUNCTION_DEF(9,16) +#define GPIO_SERIAL_IO_UART_RTS GPIO_NATIVE_FUNCTION_DEF(17,24) +#define GPIO_SERIAL_IO_UART_CTS GPIO_NATIVE_FUNCTION_DEF(25,31) +#define GPIO_SERIAL_IO_SPI_MOSI GPIO_NATIVE_FUNCTION_DEF(32,39) +#define GPIO_SERIAL_IO_SPI_MISO GPIO_NATIVE_FUNCTION_DEF(40,47) +#define GPIO_SERIAL_IO_SPI_CLK GPIO_NATIVE_FUNCTION_DEF(48,55) +#define GPIO_SERIAL_IO_SPI_CS GPIO_NATIVE_FUNCTION_DEF(56,71) +#define GPIO_ISH_GP GPIO_NATIVE_FUNCTION_DEF(80,143) +#define GPIO_ISH_UART_RX GPIO_NATIVE_FUNCTION_DEF(144,151) +#define GPIO_ISH_UART_TX GPIO_NATIVE_FUNCTION_DEF(152,159) +#define GPIO_ISH_UART_RTS GPIO_NATIVE_FUNCTION_DEF(160,167) +#define GPIO_ISH_UART_CTS GPIO_NATIVE_FUNCTION_DEF(168,175) +#define GPIO_ISH_SPI_MOSI GPIO_NATIVE_FUNCTION_DEF(184,191) +#define GPIO_ISH_SPI_MISO GPIO_NATIVE_FUNCTION_DEF(192,199) +#define GPIO_ISH_SPI_CLK GPIO_NATIVE_FUNCTION_DEF(200,207) +#define GPIO_ISH_SPI_CS GPIO_NATIVE_FUNCTION_DEF(208,223) +#define GPIO_ISH_I2C_SCL GPIO_NATIVE_FUNCTION_DEF(232,239) +#define GPIO_ISH_I2C_SDA GPIO_NATIVE_FUNCTION_DEF(240,247) +#define GPIO_THC_SPI_INT GPIO_NATIVE_FUNCTION_DEF(248,251) +#define GPIO_DMIC_DATA GPIO_NATIVE_FUNCTION_DEF(258,261) +#define GPIO_DMIC_CLKA GPIO_NATIVE_FUNCTION_DEF(262,265) +#define GPIO_DMIC_CLKB GPIO_NATIVE_FUNCTION_DEF(266,269) +#define GPIO_DDSP_HPD0 GPIO_NATIVE_FUNCTION_DEF(270,285) +#define GPIO_PANEL_AVDD_EN GPIO_NATIVE_FUNCTION_DEF(286,289) +#define GPIO_PANEL_BKLTEN GPIO_NATIVE_FUNCTION_DEF(290,293) +#define GPIO_PANEL_BKLTCTL GPIO_NATIVE_FUNCTION_DEF(294,297) +#define GPIO_PANEL_RESET GPIO_NATIVE_FUNCTION_DEF(298,301) +#define GPIO_PANEL_AVEE_EN GPIO_NATIVE_FUNCTION_DEF(302,305) +#define GPIO_PANEL_VIO_EN GPIO_NATIVE_FUNCTION_DEF(306,309) +#define GPIO_PANEL_HPD GPIO_NATIVE_FUNCTION_DEF(310,313) +#define GPIO_PANEL_TE_EN GPIO_NATIVE_FUNCTION_DEF(314,317) +#define GPIO_HDMI_GMBUS_SCL GPIO_NATIVE_FUNCTION_DEF(318,325) +#define GPIO_HDMI_GMBUS_SDA GPIO_NATIVE_FUNCTION_DEF(326,333) +#define GPIO_SERIAL_IO_I2C_SCL GPIO_NATIVE_FUNCTION_DEF(338,353) +#define GPIO_SERIAL_IO_I2C_SDA GPIO_NATIVE_FUNCTION_DEF(354,369) +#define GPIO_SD_DATA GPIO_NATIVE_FUNCTION_DEF(374,377) +#define GPIO_EMMC_DATA GPIO_NATIVE_FUNCTION_DEF(384,391) +#define GPIO_THC_CLK_LOOPBACK GPIO_NATIVE_FUNCTION_DEF(395,396) +#define GPIO_MIPI_PANEL_RESET GPIO_NATIVE_FUNCTION_DEF(401,404) +#define GPIO_MIPI_SEC_POW_EN_AVEE GPIO_NATIVE_FUNCTION_DEF(405,408) +#define GPIO_MIPI_SEC_POW_EN_AVDD GPIO_NATIVE_FUNCTION_DEF(409,412) +#define GPIO_THC_WOT GPIO_NATIVE_FUNCTION_DEF(413,414) +#define GPIO_SATA_DEVSLP GPIO_NATIVE_FUNCTION_DEF(415,446) +#define GPIO_PCIE_CLKREQ GPIO_NATIVE_FUNCTION_DEF(447,478) + +// +// Serial IO UART +// + +#define GPIO_FUNCTION_SERIAL_IO_UART_RX(UartDev) (GPIO_SERIAL_IO_UART_RX + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_TX(UartDev) (GPIO_SERIAL_IO_UART_TX + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_RTS(UartDev) (GPIO_SERIAL_IO_UART_RTS + ((UINT32)UartDev)) +#define GPIO_FUNCTION_SERIAL_IO_UART_CTS(UartDev) (GPIO_SERIAL_IO_UART_CTS + ((UINT32)UartDev)) + +// +// Serial IO SPI +// +#define GPIO_SERIAL_IO_SPI_RANGE 8 // Number of SerialIo SPIx controllers supported in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_SERIAL_IO_SPI_MOSI(SpiDev) (GPIO_SERIAL_IO_SPI_MOSI + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_MISO(SpiDev) (GPIO_SERIAL_IO_SPI_MISO + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_CLK(SpiDev) (GPIO_SERIAL_IO_SPI_CLK + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_SERIAL_IO_SPI_CS(SpiDev, CsNum) (GPIO_SERIAL_IO_SPI_CS + ((UINT32)SpiDev) + ((UINT32)CsNum) * GPIO_SERIAL_IO_SPI_RANGE) + +// +// Serial IO I2C +// + +#define GPIO_FUNCTION_SERIAL_IO_I2C_SCL(I2cDev) (GPIO_SERIAL_IO_I2C_SCL + ((UINT32)I2cDev)) +#define GPIO_FUNCTION_SERIAL_IO_I2C_SDA(I2cDev) (GPIO_SERIAL_IO_I2C_SDA + ((UINT32)I2cDev)) + +// +// ISH GP +// + +#define GPIO_FUNCTION_ISH_GP(GpNum) (GPIO_ISH_GP + ((UINT32)GpNum)) + +// +// ISH UART +// + +#define GPIO_FUNCTION_ISH_UART_RX(UartDev) (GPIO_ISH_UART_RX + ((UINT32)UartDev)) +#define GPIO_FUNCTION_ISH_UART_TX(UartDev) (GPIO_ISH_UART_TX + ((UINT32)UartDev)) +#define GPIO_FUNCTION_ISH_UART_RTS(UartDev) (GPIO_ISH_UART_RTS + ((UINT32)UartDev)) +#define GPIO_FUNCTION_ISH_UART_CTS(UartDev) (GPIO_ISH_UART_CTS + ((UINT32)UartDev)) + +// +// ISH SPI +// +#define GPIO_ISH_SPI_RANGE 8 // Number of ISH SPI controllers supported in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_ISH_SPI_MOSI(SpiDev) (GPIO_ISH_SPI_MOSI + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_MISO(SpiDev) (GPIO_ISH_SPI_MISO + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_CLK(SpiDev) (GPIO_ISH_SPI_CLK + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_ISH_SPI_CS(SpiDev, CsNum) (GPIO_ISH_SPI_CS + ((UINT32)SpiDev) + ((UINT32)CsNum) * GPIO_ISH_SPI_RANGE) + +// +// ISH I2C +// + +#define GPIO_FUNCTION_ISH_I2C_SCL(I2cDev) (GPIO_ISH_I2C_SCL + ((UINT32)I2cDev)) +#define GPIO_FUNCTION_ISH_I2C_SDA(I2cDev) (GPIO_ISH_I2C_SDA + ((UINT32)I2cDev)) + +// +// SD Card +// +#define GPIO_FUNCTION_SD_DATA(Index) (GPIO_SD_DATA + ((UINT32)Index)) + +// +// EMMC +// +#define GPIO_FUNCTION_EMMC_DATA(Index) (GPIO_EMMC_DATA + ((UINT32)Index)) + +// +// THC SPI +// + +#define GPIO_FUNCTION_THC_SPI_INT(SpiDev) (GPIO_THC_SPI_INT + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_THC_CLK_LOOPBACK(SpiDev) (GPIO_THC_CLK_LOOPBACK + ((UINT32)SpiDev)) +#define GPIO_FUNCTION_THC_WOT(SpiDev) (GPIO_THC_WOT + ((UINT32)SpiDev)) + + +// +// DMIC +// + +#define GPIO_FUNCTION_DMIC_DATA(DmicDev) (GPIO_DMIC_DATA + ((UINT32)DmicDev)) +#define GPIO_FUNCTION_DMIC_CLKA(DmicDev) (GPIO_DMIC_CLKA + ((UINT32)DmicDev)) +#define GPIO_FUNCTION_DMIC_CLKB(DmicDev) (GPIO_DMIC_CLKB + ((UINT32)DmicDev)) +#define GPIO_FUNCTION_DMIC_CLK(DmicDev) (GPIO_DMIC_CLKA + ((UINT32)DmicDev)) // If there is no split between channel A/B use A range for such Clocks + + +// +// DDSP HPD +// + +#define GPIO_FUNCTION_DDSP_HPD(HpdIndex) \ + (HpdIndex > 7) ? GPIO_DDSP_HPD0 + 8 + (HpdIndex) - 'A' : GPIO_DDSP_HPD0 + HpdIndex + +// +// HDMI_GMBUS +// + +#define GPIO_FUNCTION_HDMI_SCL(DdiPort) (GPIO_HDMI_GMBUS_SCL + ((UINT32)DdiPort)) +#define GPIO_FUNCTION_HDMI_SDA(DdiPort) (GPIO_HDMI_GMBUS_SDA + ((UINT32)DdiPort)) + +// +// Panel +// + +#define GPIO_FUNCTION_PANEL_AVDD_EN(PanelDev) (GPIO_PANEL_AVDD_EN + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_BKLTEN(PanelDev) (GPIO_PANEL_BKLTEN + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_BKLTCTL(PanelDev) (GPIO_PANEL_BKLTCTL + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_RESET(PanelDev) (GPIO_PANEL_RESET + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_AVEE_EN(PanelDev) (GPIO_PANEL_AVEE_EN + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_VIO_EN(PanelDev) (GPIO_PANEL_VIO_EN + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_HPD(PanelDev) (GPIO_PANEL_HPD + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_PANEL_TE_EN(PanelDev) (GPIO_PANEL_TE_EN + ((UINT32)PanelDev)) + +// +// MIPI +// +#define GPIO_FUNCTION_MIPI_PANEL_RESET(PanelDev) (GPIO_MIPI_PANEL_RESET + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVEE(PanelDev) (GPIO_MIPI_SEC_POW_EN_AVEE + ((UINT32)PanelDev)) +#define GPIO_FUNCTION_MIPI_SEC_POW_EN_AVDD(PanelDev) (GPIO_MIPI_SEC_POW_EN_AVDD + ((UINT32)PanelDev)) + + +// +// SATA DevSlp +// +#define GPIO_SATA_DEVSLP_RANGE 32 // Number of SATA DevSlp instances per controller supported in GPIO_NATIVE_PAD encoding + +#define GPIO_FUNCTION_SATA_DEVSLP(CsNum, SataDevSlpIndex) (GPIO_SATA_DEVSLP + ((UINT32)SataDevSlpIndex) + ((UINT32)CsNum) * GPIO_SATA_DEVSLP_RANGE) + +// +// SRC CLKREQ +// + +#define GPIO_FUNCTION_PCIE_CLKREQ(ClkReqIndex) (GPIO_PCIE_CLKREQ + ((UINT32)ClkReqIndex)) + +#endif // _GPIO_NATIVE_PADS_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h new file mode 100644 index 0000000000..a757a4b057 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/IncludePrivate/Library/GpioPrivateLib.h @@ -0,0 +1,350 @@ +/** @file + Header file for GpioPrivateLib. + All function in this library is available for PEI, DXE, and SMM, + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_PRIVATE_LIB_H_ +#define _GPIO_PRIVATE_LIB_H_ + +#include <Uefi/UefiBaseType.h> +#include <Library/GpioConfig.h> +#include <Library/PchPcrLib.h> + +/** + GPIO Standby State configuration + Standby State options for GPIO Pads +**/ +typedef enum { + GpioIosStateDefault = 0x0, + GpioIosStateLatchLastValue = (0x0 << 1) | 0x01, ///< Latch last value driven on TX, TX Enable and RX Enable + GpioIosStateTx0Rx0RxDis = (0x1 << 1) | 0x01, ///< TX: 0, RX: 0 (internally), RX disabled + GpioIosStateTx0Rx1RxDis = (0x2 << 1) | 0x01, ///< TX: 0, RX: 1 (internally), RX disabled + GpioIosStateTx1Rx0RxDis = (0x3 << 1) | 0x01, ///< TX: 1, RX: 0 (internally), RX disabled + GpioIosStateTx1Rx1RxDis = (0x4 << 1) | 0x01, ///< TX: 1, RX: 1 (internally), RX disabled + GpioIosStateTx0RxEn = (0x5 << 1) | 0x01, ///< TX: 0, RX enabled + GpioIosStateTx1RxEn = (0x6 << 1) | 0x01, ///< TX: 1, RX enabled + GpioIosStateHizRx0 = (0x7 << 1) | 0x01, ///< Hi-Z, RX: 0 (internally) + GpioIosStateHizRx1 = (0x8 << 1) | 0x01, ///< Hi-Z, RX: 1 (internally) + GpioIosStateTxDisRxEn = (0x9 << 1) | 0x01, ///< TX Disabled and RX Enabled (i.e. wake or interrupt) + GpioIosStateMasked = (0xF << 1) | 0x01 ///< IO Standby signal is masked for this pad. In this mode, a pad operates as if IOStandby has not been asserted. +} GPIO_IOSTANDBY_STATE; + +/** + GPIO Standby Term configuration + Standby Termination options for GPIO Pads +**/ +typedef enum { + GpioIosTermDefault = 0x00, + GpioIosTermSame = (0x00 << 1) | 0x01, ///< Same as state specified in Term + GpioIosTermPuDisPdDis = (0x01 << 1) | 0x01, ///< Disable Pullup and Pulldown + GpioIosTermPuDisPdEn = (0x02 << 1) | 0x01, ///< Enable Pulldown + GpioIosTermPuEnPdDis = (0x03 << 1) | 0x01 ///< Enable Pullup +} GPIO_IOSTANDBY_TERM; + +// +// Structure for native pin data +// +typedef struct { + GPIO_PAD Pad; + GPIO_PAD_MODE Mode; + GPIO_IOSTANDBY_STATE IosState; + GPIO_IOSTANDBY_TERM IosTerm; +} GPIO_PAD_NATIVE_FUNCTION; + +// +// Structure for Serial GPIO pin definition +// +typedef struct { + GPIO_PAD_NATIVE_FUNCTION Sclock; + GPIO_PAD_NATIVE_FUNCTION Sload; + GPIO_PAD_NATIVE_FUNCTION Sdataout; +} SGPIO_PINS; + +// +// Structure for USB Virtual Wire OverCurrent Pad Mode group +// +typedef struct { + GPIO_PAD OcRxPad; + GPIO_PAD OcTxPad; +} GPIO_VWOC_FUNCTION; + +// +// Below defines are based on GPIO_CONFIG structure fields +// +#define B_GPIO_PAD_MODE_MASK 0xF +#define N_GPIO_PAD_MODE_BIT_POS 0 +#define B_GPIO_DIRECTION_DIR_MASK 0x7 +#define N_GPIO_DIRECTION_DIR_BIT_POS 0 +#define B_GPIO_DIRECTION_INV_MASK 0x18 +#define N_GPIO_DIRECTION_INV_BIT_POS 3 +#define B_GPIO_OUTPUT_MASK 0x3 +#define N_GPIO_OUTPUT_BIT_POS 0 +#define N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS 0 +#define N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS 5 +#define N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS 0 +#define N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS 0 + +// +// Structure for storing information about registers offset, community, +// maximal pad number for available groups +// +typedef struct { + PCH_SBI_PID Community; + UINT16 PadOwnOffset; + UINT16 HostOwnOffset; + UINT16 GpiIsOffset; + UINT16 GpiIeOffset; + UINT16 GpiGpeStsOffset; + UINT16 GpiGpeEnOffset; + UINT16 SmiStsOffset; + UINT16 SmiEnOffset; + UINT16 NmiStsOffset; + UINT16 NmiEnOffset; + UINT16 PadCfgLockOffset; + UINT16 PadCfgLockTxOffset; + UINT16 PadCfgOffset; + UINT16 PadPerGroup; +} GPIO_GROUP_INFO; + +// +// If in GPIO_GROUP_INFO structure certain register doesn't exist +// it will have value equal to NO_REGISTER_FOR_PROPERTY +// +#define NO_REGISTER_FOR_PROPERTY 0xFFFF + +#define GPIO_PAD_DEF(Group,Pad) (UINT32)(((Group) << 16) + (Pad)) +#define GPIO_GROUP_DEF(GroupIndex,ChipsetId) ((GroupIndex) | ((ChipsetId) << 8)) +#define GPIO_GET_GROUP_INDEX(Group) ((Group) & 0x1F) +#define GPIO_GET_GROUP_FROM_PAD(GpioPad) (((GpioPad) & 0x0F1F0000) >> 16) +#define GPIO_GET_GROUP_INDEX_FROM_PAD(GpioPad) GPIO_GET_GROUP_INDEX (GPIO_GET_GROUP_FROM_PAD(GpioPad)) +#define GPIO_GET_PAD_NUMBER(GpioPad) ((GpioPad) & 0x1FF) +#define GPIO_GET_CHIPSET_ID(GpioPad) (((GpioPad) >> 24) & 0xF) + +#define GPIO_GET_PAD_POSITION(PadNumber) ((PadNumber) % 32) +#define GPIO_GET_DW_NUM(PadNumber) ((PadNumber) / 32u) + +/** + This procedure will retrieve address and length of GPIO info table + + @param[out] GpioGroupInfoTableLength Length of GPIO group table + + @retval Pointer to GPIO group table +**/ +CONST GPIO_GROUP_INFO* +GpioGetGroupInfoTable ( + OUT UINT32 *GpioGroupInfoTableLength + ); + +typedef struct { + CONST CHAR8* GpioGroupPrefix; + CONST GPIO_PAD FirstUniqueGpio; + CONST CHAR8** GroupUniqueNames; + CONST UINT32 UniqueNamesTableSize; +} GPIO_GROUP_NAME_INFO; + +// +// Helper macros for initializing GPIO_GROUP_NAME_INFO structures +// +#define GPIO_GROUP_NAME(GroupName,FirstUniqueGpio,GroupUniqueNamesTable) \ + {GroupName, FirstUniqueGpio, GroupUniqueNamesTable, ARRAY_SIZE (GroupUniqueNamesTable)} + +#define GPIO_GROUP_NAME_BASIC(GroupName) \ + {GroupName, 0, NULL, 0} + +/** + Get GPIO Chipset ID specific to PCH generation and series +**/ +UINT32 +GpioGetThisChipsetId ( + VOID + ); + +/** + This procedure is used to check if GpioPad is valid for certain chipset + + @param[in] GpioPad GPIO pad + + @retval TRUE This pin is valid on this chipset + FALSE Incorrect pin +**/ +BOOLEAN +GpioIsCorrectPadForThisChipset ( + IN GPIO_PAD GpioPad + ); + + +/** + This procedure is used by PchSmiDispatcher and will return information + needed to register GPI SMI. + + @param[in] Index GPI SMI number + @param[out] GpioPin GPIO pin + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi Registers + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN register + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioGetPadAndSmiRegs ( + IN UINT32 Index, + OUT GPIO_PAD *GpioPin, + OUT UINT8 *GpiSmiBitOffset, + OUT UINT32 *GpiHostSwOwnRegAddress, + OUT UINT32 *GpiSmiStsRegAddress + ); + +/** + This procedure calculates Pad Configuration Register DW offset + + @param[in] GpioPad GPIO pad + @param[in] DwReg Index of the configuration register + + @retval DW Register offset +**/ +UINT32 +GpioGetGpioPadCfgAddressFromGpioPad ( + IN GPIO_PAD GpioPad, + IN UINT32 DwReg + ); + + +/** + This procedure will check if GpioPad argument is valid. + Function will check below conditions: + - GpioPad represents a pad for current PCH + - GpioPad belongs to valid GpioGroup + - GPIO PadNumber is not greater than number of pads for this group + + @param[in] GpioPad GPIO pad + + @retval TRUE GPIO pad is valid and can be used with GPIO lib API + @retval FALSE GPIO pad is invalid and cannot be used with GPIO lib API +**/ +BOOLEAN +GpioIsPadValid ( + IN GPIO_PAD GpioPad + ); + +/** + This procedure will read GPIO Pad Configuration register + + @param[in] GpioPad GPIO pad + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 + + @retval PadCfgRegValue PADCFG_DWx value +**/ +UINT32 +GpioReadPadCfgReg ( + IN GPIO_PAD GpioPad, + IN UINT8 DwReg + ); + +/** + Check if 0x13 opcode supported for writing to GPIO lock unlock register + + @retval TRUE It's supported + @retval FALSE It's not supported +**/ +BOOLEAN +IsGpioLockOpcodeSupported ( + VOID + ); + +/** + Gpio Minimum Set + + Set of Gpio Minimum function to use in Pre Mem phase. + To optimise execution and reduce memory footprint thse minimum version + of 'full' functions are stripped from: + - GpioPad PCH validation + - GpioPad Group belonging validation + - GpioPad Host ownership validation + - IoStandbyState configuration + The use of below functions has to be careful and with full + understanding of all pros and cons. Please refer to GpioPrivateLib.c + to familiarize with details of implementation. +**/ + +/** + This procedure reads GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + + @retval Register value or "F"s in case of errors +**/ +UINT32 +GpioRegisterAccessRead32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register + ); + +/** + This procedure writes GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + @param[in] AndValue And value + @param[in] OrValue Or value + + @retval EFI_DEVICE_ERROR vGPIO BAR not programmed + EFI_SUCCESS Operation completed successfully +**/ +EFI_STATUS +GpioRegisterAccessAndThenOr32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register, + IN UINT32 AndValue, + IN UINT32 OrValue + ); + +/** + This procedure will calculate PADCFG register value based on GpioConfig data + The procedure can be various depending on chipset generation. + Available configuration options and corresponding registers fields + can distributed in different way in configuration registers. + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfig ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ); + +/** + This procedure will write GPIO Lock/LockTx register + - For PCH SBI message is used. + - For IBL MMIO access is used. + + @param[in] RegValue GPIO register (Lock or LockTx) value + @param[in] RegOffset GPIO register (Lock or LockTx) base offset + @param[in] DwNum Register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] GroupIndex GPIO group index in the GpioGroupInfo table + + @retval EFI_SUCCESS The function completed successfully + EFI_UNSUPPORTED Feature is not supported for this group or pad +**/ +EFI_STATUS +GpioInternalWriteLockRegister ( + IN UINT32 RegValue, + IN UINT32 RegOffset, + IN UINT32 DwNum, + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 GroupIndex + ); + +#endif // _GPIO_PRIVATE_LIB_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c new file mode 100644 index 0000000000..cf6f92a50d --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioInit.c @@ -0,0 +1,546 @@ +/** @file + This file contains routines for GPIO initialization + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" + +// +// GPIO_GROUP_DW_DATA structure is used by GpioConfigurePch function +// to cache values which will be programmed into respective GPIO registers +// after all GpioPads are processed. This way MMIO accesses are decreased +// and instead of doing one programming for one GpioPad there is only +// one access for whole register. +// +typedef struct { + UINT32 HostSoftOwnReg; + UINT32 HostSoftOwnRegMask; + UINT32 GpiGpeEnReg; + UINT32 GpiGpeEnRegMask; + UINT32 GpiNmiEnReg; + UINT32 GpiNmiEnRegMask; + UINT32 GpiSmiEnReg; + UINT32 GpiSmiEnRegMask; + UINT32 ConfigUnlockMask; + UINT32 OutputUnlockMask; +} GPIO_GROUP_DW_DATA; + +// +// GPIO_GROUP_DW_NUMBER contains number of DWords required to +// store Pad data for all groups. Each pad uses one bit. +// +// For Cannonlake only vGPIO group has >32 pads but those pads +// will not be accessed by this function so GPIO_GROUP_DW_NUMBER can be 1 +// +#define GPIO_GROUP_DW_NUMBER 1 + +/** + Get GPIO DW Register values (HOSTSW_OWN, GPE_EN, NMI_EN, Lock). + + @param[in] PadNumber GPIO pad number + @param[in] GpioConfig GPIO Config data + @param[in out] DwRegsValues Values for GPIO DW Registers + + @retval None +**/ +STATIC +VOID +GpioDwRegValueFromGpioConfig ( + IN UINT32 PadNumber, + IN CONST GPIO_CONFIG *GpioConfig, + IN OUT GPIO_GROUP_DW_DATA *GroupDwData + ) +{ + UINT32 PadBitPosition; + UINT32 DwNum; + + PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber); + DwNum = GPIO_GET_DW_NUM (PadNumber); + + if (DwNum >= GPIO_GROUP_DW_NUMBER) { + ASSERT (FALSE); + return; + } + // + // Update value to be programmed in HOSTSW_OWN register + // + GroupDwData[DwNum].HostSoftOwnRegMask |= (GpioConfig->HostSoftPadOwn & 0x1) << PadBitPosition; + GroupDwData[DwNum].HostSoftOwnReg |= (GpioConfig->HostSoftPadOwn >> 0x1) << PadBitPosition; + + // + // Update value to be programmed in GPI_GPE_EN register + // + GroupDwData[DwNum].GpiGpeEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; + GroupDwData[DwNum].GpiGpeEnReg |= ((GpioConfig->InterruptConfig & GpioIntSci) >> 3) << PadBitPosition; + + // + // Update value to be programmed in GPI_NMI_EN register + // + GroupDwData[DwNum].GpiNmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; + GroupDwData[DwNum].GpiNmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntNmi) >> 1) << PadBitPosition; + + // + // Update value to be programmed in GPI_SMI_EN register + GroupDwData[DwNum].GpiSmiEnRegMask |= (GpioConfig->InterruptConfig & 0x1) << PadBitPosition; + GroupDwData[DwNum].GpiSmiEnReg |= ((GpioConfig->InterruptConfig & GpioIntSmi) >> 2) << PadBitPosition; + if ((GpioConfig->InterruptConfig & GpioIntSmi) == GpioIntSmi) { + GroupDwData[DwNum].HostSoftOwnRegMask |= 1 << PadBitPosition; + GroupDwData[DwNum].HostSoftOwnReg |= 1 << PadBitPosition; + } + + // + // Update information on Pad Configuration Lock + // + GroupDwData[DwNum].ConfigUnlockMask |= ((GpioConfig->LockConfig >> 1) & 0x1) << PadBitPosition; + + // + // Update information on Pad Configuration Lock Tx + // + GroupDwData[DwNum].OutputUnlockMask |= ((GpioConfig->LockConfig >> 3) & 0x1) << PadBitPosition; + + // + // if pad in GpioMode is an output default action should be to leave output unlocked + // + if ((GpioConfig->PadMode == GpioPadModeGpio) && + (GpioConfig->Direction == GpioDirOut) && + ((GpioConfig->LockConfig & B_GPIO_LOCK_CONFIG_OUTPUT_LOCK_MASK) == GpioLockDefault)) { + GroupDwData[DwNum].OutputUnlockMask |= 0x1 << PadBitPosition; + } +} + +/** + This internal procedure will scan GPIO initialization table and unlock + all pads present in it + + @param[in] NumberOfItem Number of GPIO pad records in table + @param[in] GpioInitTableAddress GPIO initialization table + @param[in] Index Index of GPIO Initialization table record + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioUnlockPadsForAGroup ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress, + IN UINT32 Index + ) +{ + UINT32 PadsToUnlock[GPIO_GROUP_DW_NUMBER]; + UINT32 DwNum; + UINT32 PadBitPosition; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + CONST GPIO_INIT_CONFIG *GpioData; + GPIO_GROUP Group; + UINT32 GroupIndex; + UINT32 PadNumber; + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GpioData = &GpioInitTableAddress[Index]; + Group = GpioGetGroupFromGpioPad (GpioData->GpioPad); + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); + + ZeroMem (PadsToUnlock, sizeof (PadsToUnlock)); + // + // Loop through pads for one group. If pad belongs to a different group then + // break and move to register programming. + // + while (Index < NumberOfItems) { + + GpioData = &GpioInitTableAddress[Index]; + if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) { + //if next pad is from different group then break loop + break; + } + + PadNumber = GpioGetPadNumberFromGpioPad (GpioData->GpioPad); + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex)); + return EFI_INVALID_PARAMETER; + } + + PadBitPosition = GPIO_GET_PAD_POSITION (PadNumber); + DwNum = GPIO_GET_DW_NUM (PadNumber); + + if (DwNum >= GPIO_GROUP_DW_NUMBER) { + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + // + // Update pads which need to be unlocked + // + PadsToUnlock[DwNum] |= 0x1 << PadBitPosition; + + //Move to next item + Index++; + } + + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1); DwNum++) { + // + // Unlock pads + // + if (PadsToUnlock[DwNum] != 0) { + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadsToUnlock[DwNum]); + GpioUnlockPadCfgTxForGroupDw (Group, DwNum, PadsToUnlock[DwNum]); + } + } + + return EFI_SUCCESS; +} + +/** + This procedure will initialize multiple PCH GPIO pins + + @param[in] NumberofItem Number of GPIO pads to be updated + @param[in] GpioInitTableAddress GPIO initialization table + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioConfigurePch ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress + ) +{ + UINT32 Index; + UINT32 PadCfgDwReg[GPIO_PADCFG_DW_REG_NUMBER]; + UINT32 PadCfgDwRegMask[GPIO_PADCFG_DW_REG_NUMBER]; + UINT32 PadCfgReg; + GPIO_GROUP_DW_DATA GroupDwData[GPIO_GROUP_DW_NUMBER]; + UINT32 DwNum; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + GPIO_PAD_OWN PadOwnVal; + CONST GPIO_INIT_CONFIG *GpioData; + UINT32 GroupIndex; + UINT32 PadNumber; + UINT32 DwRegIndex; + + PadOwnVal = GpioPadOwnHost; + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + Index = 0; + while (Index < NumberOfItems) { + + GpioData = &GpioInitTableAddress[Index]; + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioData->GpioPad); + + DEBUG_CODE_BEGIN(); + if (!GpioIsCorrectPadForThisChipset (GpioData->GpioPad)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioData->GpioPad)); + ASSERT (FALSE); + return EFI_UNSUPPORTED; + } + DEBUG_CODE_END (); + + // + // Unlock pads for a given group which are going to be reconfigured + // + // + // Because PADCFGLOCK/LOCKTX register reset domain is Powergood, lock settings + // will get back to default only after G3 or DeepSx transition. On the other hand GpioPads + // configuration is controlled by a configurable type of reset - PadRstCfg. This means that if + // PadRstCfg != Powergood GpioPad will have its configuration locked despite it being not the + // one desired by BIOS. Before reconfiguring all pads they will get unlocked. + // + GpioUnlockPadsForAGroup (NumberOfItems, GpioInitTableAddress, Index); + + ZeroMem (GroupDwData, sizeof (GroupDwData)); + // + // Loop through pads for one group. If pad belongs to a different group then + // break and move to register programming. + // + while (Index < NumberOfItems) { + + GpioData = &GpioInitTableAddress[Index]; + if (GroupIndex != GpioGetGroupIndexFromGpioPad (GpioData->GpioPad)) { + //if next pad is from different group then break loop + break; + } + + PadNumber = GpioGetPadNumberFromGpioPad (GpioData->GpioPad); + + DEBUG_CODE_BEGIN (); + // + // Check if legal pin number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds possible range for group %d\n", PadNumber, GroupIndex)); + return EFI_INVALID_PARAMETER; + } + + // + // Check if selected GPIO Pad is not owned by CSME/ISH + // + GpioGetPadOwnership (GpioData->GpioPad, &PadOwnVal); + + if (PadOwnVal != GpioPadOwnHost) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Accessing pad not owned by host (Group=%d, Pad=%d)!\n", GroupIndex, PadNumber)); + DEBUG ((DEBUG_ERROR, "** Please make sure the GPIO usage in sync between CSME and BIOS configuration. \n")); + DEBUG ((DEBUG_ERROR, "** All the GPIO occupied by CSME should not do any configuration by BIOS.\n")); + //Move to next item + goto move_to_next_index; + } + + // + // Check if Pad enabled for SCI is to be in unlocked state + // + if (((GpioData->GpioConfig.InterruptConfig & GpioIntSci) == GpioIntSci) && + ((GpioData->GpioConfig.LockConfig & B_GPIO_LOCK_CONFIG_PAD_CONF_LOCK_MASK) != GpioPadConfigUnlock)){ + DEBUG ((DEBUG_ERROR, "GPIO ERROR: GPIO used for SCI is not unlocked!\n")); + ASSERT (FALSE); + return EFI_INVALID_PARAMETER; + } + DEBUG_CODE_END (); + + ZeroMem (PadCfgDwReg, sizeof (PadCfgDwReg)); + ZeroMem (PadCfgDwRegMask, sizeof (PadCfgDwRegMask)); + // + // Get GPIO PADCFG register value from GPIO config data + // + GpioPadCfgRegValueFromGpioConfig ( + GpioData->GpioPad, + &GpioData->GpioConfig, + PadCfgDwReg, + PadCfgDwRegMask + ); + + // + // Write PADCFG DW0, DW1, DW2 registers + // + for (DwRegIndex = 0; DwRegIndex <= 2; DwRegIndex++) { + PadCfgReg = GpioGetGpioPadCfgAddressFromGpioPad (GpioData->GpioPad, DwRegIndex); + if (PadCfgReg != 0) { + GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], PadCfgReg, ~PadCfgDwRegMask[DwRegIndex], PadCfgDwReg[DwRegIndex]); + } + } + + // + // Get GPIO DW register values from GPIO config data + // + GpioDwRegValueFromGpioConfig ( + PadNumber, + &GpioData->GpioConfig, + GroupDwData + ); + + move_to_next_index: + //Move to next item + Index++; + } + + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { + // + // Write HOSTSW_OWN registers + // + if (GpioGroupInfo[GroupIndex].HostOwnOffset != NO_REGISTER_FOR_PROPERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].HostOwnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].HostSoftOwnRegMask, + GroupDwData[DwNum].HostSoftOwnReg + ); + } + + // + // Write GPI_GPE_EN registers + // + if (GpioGroupInfo[GroupIndex].GpiGpeEnOffset != NO_REGISTER_FOR_PROPERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiGpeEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiGpeEnRegMask, + GroupDwData[DwNum].GpiGpeEnReg + ); + } + + // + // Write GPI_NMI_EN registers + // + if (GpioGroupInfo[GroupIndex].NmiEnOffset != NO_REGISTER_FOR_PROPERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].NmiEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiNmiEnRegMask, + GroupDwData[DwNum].GpiNmiEnReg + ); + } else if (GroupDwData[DwNum].GpiNmiEnReg != 0x0) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting NMI\n", GroupIndex)); + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + } + + // + // Write GPI_SMI_EN registers + // + if (GpioGroupInfo[GroupIndex].SmiEnOffset != NO_REGISTER_FOR_PROPERTY) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].SmiEnOffset + DwNum * 0x4, + ~GroupDwData[DwNum].GpiSmiEnRegMask, + GroupDwData[DwNum].GpiSmiEnReg + ); + } else if (GroupDwData[DwNum].GpiSmiEnReg != 0x0) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group %d has no pads supporting SMI\n", GroupIndex)); + ASSERT_EFI_ERROR (EFI_UNSUPPORTED); + } + + // + // Update Pad Configuration unlock data + // + if (GroupDwData[DwNum].ConfigUnlockMask) { + GpioStoreGroupDwUnlockPadConfigData (GroupIndex, DwNum, GroupDwData[DwNum].ConfigUnlockMask); + } + + // + // Update Pad Output unlock data + // + if (GroupDwData[DwNum].OutputUnlockMask) { + GpioStoreGroupDwUnlockOutputData (GroupIndex, DwNum, GroupDwData[DwNum].OutputUnlockMask); + } + } + } + + return EFI_SUCCESS; +} + +/** + This procedure will clear all status bits of any GPIO interrupts. + + @param[in] none + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +STATIC +EFI_STATUS +GpioClearAllGpioInterrupts ( + VOID + ) +{ + GPIO_GROUP Group; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + GPIO_GROUP GpioGroupLowest; + GPIO_GROUP GpioGroupHighest; + UINT32 GroupIndex; + UINT32 GpioGroupInfoLength; + UINT32 DwNum; + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GpioGroupLowest = GpioGetLowestGroup (); + GpioGroupHighest = GpioGetHighestGroup (); + + for (Group = GpioGroupLowest; Group <= GpioGroupHighest; Group++) { + GroupIndex = GpioGetGroupIndexFromGroup (Group); + // + // Check if group has GPI IS register + // + if (GpioGroupInfo[GroupIndex].GpiIsOffset != NO_REGISTER_FOR_PROPERTY) { + // + // Clear all GPI_IS Status bits by writing '1' + // + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiIsOffset + DwNum * 0x4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has GPI_GPE_STS register + // + if (GpioGroupInfo[GroupIndex].GpiGpeStsOffset != NO_REGISTER_FOR_PROPERTY) { + // + // Clear all GPI_GPE_STS Status bits by writing '1' + // + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].GpiGpeStsOffset + DwNum * 0x4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has SMI_STS register + // + if (GpioGroupInfo[GroupIndex].SmiStsOffset != NO_REGISTER_FOR_PROPERTY) { + // + // Clear all SMI_STS Status bits by writing '1' + // + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].SmiStsOffset + DwNum * 4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + // + // Check if group has NMI_STS register + // + if (GpioGroupInfo[GroupIndex].NmiStsOffset != NO_REGISTER_FOR_PROPERTY) { + // + // Clear all NMI_STS Status bits by writing '1' + // + for (DwNum = 0; DwNum <= GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup); DwNum++) { + GpioRegisterAccessAndThenOr32 ( + &GpioGroupInfo[GroupIndex], + GpioGroupInfo[GroupIndex].NmiStsOffset + DwNum * 4, + ~(UINT32)0, + 0xFFFFFFFF + ); + } + } + + } + return EFI_SUCCESS; +} + +/** + This procedure will initialize multiple GPIO pins. Use GPIO_INIT_CONFIG structure. + Structure contains fields that can be used to configure each pad. + Pad not configured using GPIO_INIT_CONFIG will be left with hardware default values. + Separate fields could be set to hardware default if it does not matter, except + GpioPad and PadMode. + Function will work in most efficient way if pads which belong to the same group are + placed in adjacent records of the table. + Although function can enable pads for Native mode, such programming is done + by reference code when enabling related silicon feature. + + @param[in] NumberofItem Number of GPIO pads to be updated + @param[in] GpioInitTableAddress GPIO initialization table + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioConfigurePads ( + IN UINT32 NumberOfItems, + IN GPIO_INIT_CONFIG *GpioInitTableAddress + ) +{ + EFI_STATUS Status; + + Status = GpioConfigurePch (NumberOfItems, GpioInitTableAddress); + + GpioClearAllGpioInterrupts (); + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c new file mode 100644 index 0000000000..19daed97c0 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLib.c @@ -0,0 +1,522 @@ +/** @file + This file contains routines for GPIO + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" +#include <Register/PchPcrRegs.h> + +/** + This procedure will check if GpioGroup argument is correct and + supplied DW reg number can be used for this group to access DW registers. + Function will check below conditions: + - Valid GpioGroup + - DwNum is has valid value for this group + + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (parameter applicable in accessing whole register). + For group which has less then 32 pads per group DwNum must be 0. + + @retval TRUE DW Reg number and GpioGroup is valid + @retval FALSE DW Reg number and GpioGroup is invalid +**/ +STATIC +BOOLEAN +GpioIsGroupAndDwNumValid ( + IN GPIO_GROUP Group, + IN UINT32 DwNum + ) +{ + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + GroupIndex = GpioGetGroupIndexFromGroup (Group); + + if ((Group < GpioGetLowestGroup ()) || (Group > GpioGetHighestGroup ()) || (GroupIndex >= GpioGroupInfoLength)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Group argument (%d) is not within range of possible groups for this PCH\n", GroupIndex)); + goto Error; + } + + // + // Check if DwNum argument does not exceed number of DWord registers + // resulting from available pads for certain group + // + if (DwNum > GPIO_GET_DW_NUM (GpioGroupInfo[GroupIndex].PadPerGroup - 1)){ + goto Error; + } + + return TRUE; +Error: + ASSERT (FALSE); + return FALSE; +} + +// +// Possible registers to be accessed using GpioReadReg()/GpioWriteReg() functions +// +typedef enum { + GpioHostOwnershipRegister = 0, + GpioGpeEnableRegister, + GpioGpeStatusRegister, + GpioSmiEnableRegister, + GpioSmiStatusRegister, + GpioNmiEnableRegister, + GpioPadConfigLockRegister, + GpioPadLockOutputRegister +} GPIO_REG; + +/** + This procedure will read GPIO register + + @param[in] RegType GPIO register type + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (parameter applicable in accessing whole register). + For group which has less then 32 pads per group DwNum must be 0. + @param[out] ReadVal Read data + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group or pad +**/ +STATIC +EFI_STATUS +GpioReadReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *ReadVal + ) +{ + UINT32 RegOffset; + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + + RegOffset = NO_REGISTER_FOR_PROPERTY; + GroupIndex = GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioHostOwnershipRegister: + RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset; + break; + case GpioGpeEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset; + break; + case GpioGpeStatusRegister: + RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset; + break; + case GpioSmiEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset; + break; + case GpioSmiStatusRegister: + RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset; + break; + case GpioNmiEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset; + break; + case GpioPadConfigLockRegister: + RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset; + break; + case GpioPadLockOutputRegister: + RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; + break; + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset == NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // + if ((RegType == GpioPadConfigLockRegister) || (RegType == GpioPadLockOutputRegister)) { + // + // PadConfigLock and OutputLock registers when used for group containing more than 32 pads + // are not placed in a continuous way, e.g: + // 0x0 - PadConfigLock_DW0 + // 0x4 - OutputLock_DW0 + // 0x8 - PadConfigLock_DW1 + // 0xC - OutputLock_DW1 + // + RegOffset += DwNum * 0x8; + } else { + RegOffset += DwNum * 0x4; + } + + *ReadVal = GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], RegOffset); + + return EFI_SUCCESS; +} + +/** + This procedure will write GPIO register + + @param[in] RegType GPIO register type + @param[in] Group GPIO group + @param[in] DwNum Register number for current group (parameter applicable in accessing whole register). + For group which has less then 32 pads per group DwNum must be 0. + @param[in] RegAndMask Mask which will be AND'ed with register value + @param[in] RegOrMask Mask which will be OR'ed with register value + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group or pad +**/ +STATIC +EFI_STATUS +GpioWriteReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 RegAndMask, + IN UINT32 RegOrMask + ) +{ + UINT32 RegOffset; + UINT32 GroupIndex; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadCfgLock; + BOOLEAN Lockable; + + Lockable = FALSE; + PadCfgLock = 0; + RegOffset = NO_REGISTER_FOR_PROPERTY; + GroupIndex = GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioHostOwnershipRegister: + RegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset; + break; + case GpioGpeEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].GpiGpeEnOffset; + Lockable = TRUE; + break; + case GpioGpeStatusRegister: + RegOffset = GpioGroupInfo[GroupIndex].GpiGpeStsOffset; + break; + case GpioSmiEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].SmiEnOffset; + Lockable = TRUE; + break; + case GpioSmiStatusRegister: + RegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset; + break; + case GpioNmiEnableRegister: + RegOffset = GpioGroupInfo[GroupIndex].NmiEnOffset; + Lockable = TRUE; + break; + case GpioPadConfigLockRegister: + case GpioPadLockOutputRegister: + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset == NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + if (Lockable) { + GpioGetPadCfgLockForGroupDw (Group, DwNum, &PadCfgLock); + if (PadCfgLock) { + // + // Check if for pads which are going to be reconfigured lock is set. + // + if ((~RegAndMask | RegOrMask) & PadCfgLock) { + // + // Unlock all pads for this Group DW reg for simplicity + // even if not all of those pads will have their settings reprogrammed + // + GpioUnlockPadCfgForGroupDw (Group, DwNum, PadCfgLock); + } else { + // + // No need to perform an unlock as pads which are going to be reconfigured + // are not in locked state + // + PadCfgLock = 0; + } + } + } + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // + RegOffset += DwNum * 0x4; + + GpioRegisterAccessAndThenOr32 (&GpioGroupInfo[GroupIndex], RegOffset, RegAndMask,RegOrMask); + + if (Lockable && PadCfgLock) { + // + // Lock previously unlocked pads + // + GpioLockPadCfgForGroupDw (Group, DwNum, PadCfgLock); + } + + return EFI_SUCCESS; +} + +/** + This procedure will write GPIO Lock/LockTx register using SBI. + + @param[in] RegType GPIO register (Lock or LockTx) + @param[in] Group GPIO group number + @param[in] DwNum Register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] LockRegAndMask Mask which will be AND'ed with Lock register value + @param[in] LockRegOrMask Mask which will be Or'ed with Lock register value + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_UNSUPPORTED Feature is not supported for this group or pad +**/ +STATIC +EFI_STATUS +GpioWriteLockReg ( + IN GPIO_REG RegType, + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 LockRegAndMask, + IN UINT32 LockRegOrMask + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 RegOffset; + UINT32 OldLockVal; + UINT32 NewLockVal; + UINT32 GroupIndex; + + OldLockVal = 0; + NewLockVal = 0; + + RegOffset = NO_REGISTER_FOR_PROPERTY; + GroupIndex = GpioGetGroupIndexFromGroup (Group); + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + switch (RegType) { + case GpioPadConfigLockRegister: + RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockOffset; + GpioGetPadCfgLockForGroupDw (Group, DwNum, &OldLockVal); + break; + case GpioPadLockOutputRegister: + RegOffset = GpioGroupInfo[GroupIndex].PadCfgLockTxOffset; + GpioGetPadCfgLockTxForGroupDw (Group, DwNum, &OldLockVal); + break; + default: + break; + } + + // + // Check if selected register exists + // + if (RegOffset == NO_REGISTER_FOR_PROPERTY) { + return EFI_UNSUPPORTED; + } + + NewLockVal = (OldLockVal & LockRegAndMask) | LockRegOrMask; + + return GpioInternalWriteLockRegister (NewLockVal, RegOffset, DwNum, GpioGroupInfo, GroupIndex); +} + +/** + This procedure will get Gpio Pad Ownership + + @param[in] GpioPad GPIO pad + @param[out] PadOwnVal Value of Pad Ownership + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioGetPadOwnership ( + IN GPIO_PAD GpioPad, + OUT GPIO_PAD_OWN *PadOwnVal + ) +{ + UINT32 Mask; + UINT32 RegOffset; + UINT32 GroupIndex; + UINT32 PadNumber; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadOwnRegValue; + + if (!GpioIsPadValid (GpioPad)) { + return EFI_INVALID_PARAMETER; + } + + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad); + PadNumber = GpioGetPadNumberFromGpioPad (GpioPad); + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Check if selected register exists + // + if (GpioGroupInfo[GroupIndex].PadOwnOffset == NO_REGISTER_FOR_PROPERTY) { + *PadOwnVal = GpioPadOwnHost; + return EFI_UNSUPPORTED; + } + // + // Calculate RegOffset using Pad Ownership offset and GPIO Pad number. + // One DWord register contains information for 8 pads. + // + RegOffset = GpioGroupInfo[GroupIndex].PadOwnOffset + (PadNumber >> 3) * 0x4; + + // + // Calculate pad bit position within DWord register + // + PadNumber %= 8; + Mask = (BIT1 | BIT0) << (PadNumber * 4); + + PadOwnRegValue = GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], RegOffset); + + *PadOwnVal = (GPIO_PAD_OWN) ((PadOwnRegValue & Mask) >> (PadNumber * 4)); + + return EFI_SUCCESS; +} + +/** + This procedure will check state of Pad Config Lock for pads within one group + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLock register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[out] PadCfgLockRegVal Value of PadCfgLock register + Bit position - PadNumber + Bit value - 0: NotLocked, 1: Locked + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number +**/ +EFI_STATUS +GpioGetPadCfgLockForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *PadCfgLockRegVal + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioReadReg ( + GpioPadConfigLockRegister, + Group, + DwNum, + PadCfgLockRegVal + ); +} +/** + This procedure will check state of Pad Config Tx Lock for pads within one group + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLockTx register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[out] PadCfgLockTxRegVal Value of PadCfgLockTx register + Bit position - PadNumber + Bit value - 0: NotLockedTx, 1: LockedTx + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or DwNum parameter number +**/ +EFI_STATUS +GpioGetPadCfgLockTxForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + OUT UINT32 *PadCfgLockTxRegVal + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioReadReg ( + GpioPadLockOutputRegister, + Group, + DwNum, + PadCfgLockTxRegVal + ); +} +/** + This procedure will clear PadCfgLock for selected pads within one group. + This function should be used only inside SMI. + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLock register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] PadsToUnlock Bitmask for pads which are going to be unlocked, + Bit position - PadNumber + Bit value - 0: DoNotUnlock, 1: Unlock + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioUnlockPadCfgForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 PadsToUnlock + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioWriteLockReg ( + GpioPadConfigLockRegister, + Group, + DwNum, + ~PadsToUnlock, + 0 + ); +} +/** + This procedure will clear PadCfgLockTx for selected pads within one group. + This function should be used only inside SMI. + + @param[in] Group GPIO group + @param[in] DwNum PadCfgLockTx register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] PadsToUnlockTx Bitmask for pads which are going to be unlocked, + Bit position - PadNumber + Bit value - 0: DoNotUnLockTx, 1: LockTx + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioUnlockPadCfgTxForGroupDw ( + IN GPIO_GROUP Group, + IN UINT32 DwNum, + IN UINT32 PadsToUnlockTx + ) +{ + if (!GpioIsGroupAndDwNumValid (Group, DwNum)) { + return EFI_INVALID_PARAMETER; + } + + return GpioWriteLockReg ( + GpioPadLockOutputRegister, + Group, + DwNum, + ~PadsToUnlockTx, + 0 + ); +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h new file mode 100644 index 0000000000..2c2b4ee75c --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioLibrary.h @@ -0,0 +1,29 @@ +/** @file + Header file for GPIO Lib implementation. + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_LIBRARY_H_ +#define _GPIO_LIBRARY_H_ + +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/GpioLib.h> +#include <Library/GpioNativeLib.h> +#include <Library/GpioPrivateLib.h> +#include <Library/PchInfoLib.h> +#include <Library/PchCycleDecodingLib.h> +#include <Library/PmcPrivateLib.h> +#include <Library/GpioHelpersLib.h> +#include <Register/GpioRegs.h> + +// +// Number of PADCFG_DW registers +// +#define GPIO_PADCFG_DW_REG_NUMBER 4 + +#endif // _GPIO_LIBRARY_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c new file mode 100644 index 0000000000..4e4c53e588 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/GpioNativeLib.c @@ -0,0 +1,177 @@ +/** @file + This file contains routines for GPIO native and chipset specific usage + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include "GpioLibrary.h" + +/** + This procedure will get number of pads for certain GPIO group + + @param[in] Group GPIO group number + + @retval Value Pad number for group + If illegal group number then return 0 +**/ +UINT32 +GpioGetPadPerGroup ( + IN GPIO_GROUP Group + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 GroupIndex; + // + // Check if group argument exceeds GPIO GROUP INFO array + // + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + GroupIndex = GpioGetGroupIndexFromGroup (Group); + + if ((UINTN) GroupIndex >= GpioGroupInfoLength) { + return 0; + } else { + return GpioGroupInfo[GroupIndex].PadPerGroup; + } +} + +/** + This procedure will get number of groups + + @param[in] none + + @retval Value Group number +**/ +UINT32 +GpioGetNumberOfGroups ( + VOID + ) +{ + UINT32 GpioGroupInfoLength; + + GpioGetGroupInfoTable (&GpioGroupInfoLength); + return GpioGroupInfoLength; +} +/** + This procedure will get lowest group + + @param[in] none + + @retval Value Lowest Group +**/ +GPIO_GROUP +GpioGetLowestGroup ( + VOID + ) +{ + return GpioGetGroupFromGroupIndex (0); +} +/** + This procedure will get highest group + + @param[in] none + + @retval Value Highest Group +**/ +GPIO_GROUP +GpioGetHighestGroup ( + VOID + ) +{ + return GpioGetGroupFromGroupIndex (GpioGetNumberOfGroups () - 1); +} + +/** + This procedure will get group number + + @param[in] GpioPad Gpio Pad + + @retval Value Group number +**/ +GPIO_GROUP +GpioGetGroupFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return GPIO_GET_GROUP_FROM_PAD (GpioPad); +} + +/** + This procedure will get group index (0 based) + + @param[in] GpioPad Gpio Pad + + @retval Value Group Index +**/ +UINT32 +GpioGetGroupIndexFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return (UINT32) GPIO_GET_GROUP_INDEX_FROM_PAD (GpioPad); +} + +/** + This procedure will get group index (0 based) from group + + @param[in] GpioGroup Gpio Group + + @retval Value Group Index +**/ +UINT32 +GpioGetGroupIndexFromGroup ( + IN GPIO_GROUP GpioGroup + ) +{ + return (UINT32) GPIO_GET_GROUP_INDEX (GpioGroup); +} + +/** + This procedure will get group from group index (0 based) + + @param[in] GroupIndex Group Index + + @retval GpioGroup Gpio Group +**/ +GPIO_GROUP +GpioGetGroupFromGroupIndex ( + IN UINT32 GroupIndex + ) +{ + return GPIO_GROUP_DEF (GroupIndex, GpioGetThisChipsetId ()); +} + +/** + This procedure will get pad number (0 based) from Gpio Pad + + @param[in] GpioPad Gpio Pad + + @retval Value Pad Number +**/ +UINT32 +GpioGetPadNumberFromGpioPad ( + IN GPIO_PAD GpioPad + ) +{ + return (UINT32) GPIO_GET_PAD_NUMBER (GpioPad); +} +/** + This procedure will return GpioPad from Group and PadNumber + + @param[in] Group GPIO group + @param[in] PadNumber GPIO PadNumber + + @retval GpioPad GpioPad +**/ +GPIO_PAD +GpioGetGpioPadFromGroupAndPadNumber ( + IN GPIO_GROUP Group, + IN UINT32 PadNumber + ) +{ + if (IsPchLp ()) { + return GPIO_PAD_DEF (Group,PadNumber); + } else { + return GPIO_PAD_DEF (Group,PadNumber); + } +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf new file mode 100644 index 0000000000..21fb4417c1 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/Library/PeiDxeSmmGpioLib/PeiDxeSmmGpioLib.inf @@ -0,0 +1,44 @@ +## @file +# Component description file for the PeiDxeSmmGpioLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmGpioLib +FILE_GUID = 16EC5CA8-8195-4847-B6CB-662BD7B763F2 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = GpioLib +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +PrintLib +PchCycleDecodingLib +PchSbiAccessLib +PmcPrivateLib +GpioPrivateLib +GpioHelpersLib + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +GpioLib.c +GpioNativeLib.c +GpioInit.c +GpioLibrary.h diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c new file mode 100644 index 0000000000..b4b6c14329 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.c @@ -0,0 +1,51 @@ +/** @file + This file contains NULL implementation for GPIO Helpers Lib + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Uefi/UefiBaseType.h> +#include <Library/GpioConfig.h> + +/** + This procedure stores GPIO group data about pads which PadConfig needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockPadConfigData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ) +{ + return EFI_SUCCESS; +} + +/** + This procedure stores GPIO group data about pads which Output state needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockOutputData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ) +{ + return EFI_SUCCESS; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf new file mode 100644 index 0000000000..91d81af4b9 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/BaseGpioHelpersLibNull/BaseGpioHelpersLibNull.inf @@ -0,0 +1,25 @@ +## @file +# Component description file for the NULL GpioHelpersLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = BaseGpioHelpersLib +FILE_GUID = AB282608-2A50-4AE3-9242-64064ECF40D4 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = GpioHelpersLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +BaseGpioHelpersLibNull.c + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h new file mode 100644 index 0000000000..480990cb62 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioNativePrivateLibInternal.h @@ -0,0 +1,48 @@ +/** @file + Header file for GPIO Private Lib Internal functions. + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#ifndef _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ +#define _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ + +#include <Library/GpioPrivateLib.h> + + +/** + This function provides recommended GPIO IO Standby configuration for a given native function + + @param[in] PadFunction PadFunction for a specific native signal. Please refer to GpioNativePads.h + @param[out] StandbyState IO Standby State for specified native function + @param[out] StandbyTerm IO Standby Termination for specified native function + + @retval Status +**/ +EFI_STATUS +GpioGetFunctionIoStandbyConfig ( + IN UINT32 PadFunction, + OUT GPIO_IOSTANDBY_STATE *StandbyState, + OUT GPIO_IOSTANDBY_TERM *StandbyTerm + ); + +/** + This procedure will calculate PADCFG register value based on GpioConfig data + For physical/local/hard (not virtual) GPIO pads + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfigHardGpio ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ); + +#endif // _GPIO_NATIVE_PRIVATE_LIB_INTERNAL_H_ diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c new file mode 100644 index 0000000000..7d5fa9fafd --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLib.c @@ -0,0 +1,267 @@ +/** @file + This file contains GPIO routines for RC usage + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/GpioLib.h> +#include <Library/GpioNativeLib.h> +#include <Library/GpioPrivateLib.h> +#include <Library/GpioNativePads.h> +#include <Register/GpioRegs.h> +#include "GpioNativePrivateLibInternal.h" + +/** + This procedure is used to check if GpioPad is valid for certain chipset + + @param[in] GpioPad GPIO pad + + @retval TRUE This pin is valid on this chipset + FALSE Incorrect pin +**/ +BOOLEAN +GpioIsCorrectPadForThisChipset ( + IN GPIO_PAD GpioPad + ) +{ + return ((GPIO_GET_CHIPSET_ID (GpioPad) == GpioGetThisChipsetId ()) && + (GpioGetGroupIndexFromGpioPad (GpioPad) < GpioGetNumberOfGroups ())); +} + +/** + This procedure is used by PchSmiDispatcher and will return information + needed to register GPI SMI. + + @param[in] Index GPI SMI number + @param[out] GpioPin GPIO pin + @param[out] GpiSmiBitOffset GPI SMI bit position within GpiSmi Registers + @param[out] GpiHostSwOwnRegAddress Address of HOSTSW_OWN register + @param[out] GpiSmiStsRegAddress Address of GPI SMI status register + + @retval EFI_SUCCESS The function completed successfully + @retval EFI_INVALID_PARAMETER Invalid group or pad number +**/ +EFI_STATUS +GpioGetPadAndSmiRegs ( + IN UINT32 Index, + OUT GPIO_PAD *GpioPin, + OUT UINT8 *GpiSmiBitOffset, + OUT UINT32 *GpiHostSwOwnRegAddress, + OUT UINT32 *GpiSmiStsRegAddress + ) +{ + UINT32 GroupIndex; + UINT32 PadNumber; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + GPIO_GROUP GpioGroup; + UINT32 GpioGroupInfoLength; + UINT32 SmiStsRegOffset; + UINT32 HostSwOwnRegOffset; + GPIO_PAD_OWN PadOwnVal; + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + PadNumber = 0; + GroupIndex = 0; + for (GroupIndex = 0; GroupIndex < GpioGroupInfoLength; GroupIndex++) { + PadNumber = Index; + if (PadNumber < GpioGroupInfo[GroupIndex].PadPerGroup) { + // + // Found group and pad number + // + break; + } + Index = Index - GpioGroupInfo[GroupIndex].PadPerGroup; + } + + // + // Check if legal pad number + // + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup){ + return EFI_INVALID_PARAMETER; + } + + // + // Check if selected group has GPI SMI Enable and Status registers + // + if (GpioGroupInfo[GroupIndex].SmiEnOffset == NO_REGISTER_FOR_PROPERTY) { + return EFI_INVALID_PARAMETER; + } + + GpioGroup = GpioGetGroupFromGroupIndex (GroupIndex); + *GpioPin = GpioGetGpioPadFromGroupAndPadNumber (GpioGroup, PadNumber); + + DEBUG_CODE_BEGIN (); + // + // Check if selected GPIO Pad is not owned by CSME/ISH/IE + // + GpioGetPadOwnership (*GpioPin, &PadOwnVal); + if (PadOwnVal != GpioPadOwnHost) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: GPIO not owned by host!\n")); + return EFI_INVALID_PARAMETER; + } + DEBUG_CODE_END (); + + *GpiSmiBitOffset = (UINT8)(PadNumber % 32); + + HostSwOwnRegOffset = GpioGroupInfo[GroupIndex].HostOwnOffset + (PadNumber / 32) * 0x4; + *GpiHostSwOwnRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, HostSwOwnRegOffset); + + SmiStsRegOffset = GpioGroupInfo[GroupIndex].SmiStsOffset + (PadNumber / 32) * 0x4; + *GpiSmiStsRegAddress = PCH_PCR_ADDRESS (GpioGroupInfo[GroupIndex].Community, SmiStsRegOffset); + + return EFI_SUCCESS; +} + +/** + This procedure will check if GpioPad argument is valid. + Function will check below conditions: + - GpioPad represents a pad for current PCH + - GpioPad belongs to valid GpioGroup + - GPIO PadNumber is not greater than number of pads for this group + + @param[in] GpioPad GPIO pad + + @retval TRUE GPIO pad is valid and can be used with GPIO lib API + @retval FALSE GPIO pad is invalid and cannot be used with GPIO lib API +**/ +BOOLEAN +GpioIsPadValid ( + IN GPIO_PAD GpioPad + ) +{ + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 PadNumber; + UINT32 GroupIndex; + + if (!GpioIsCorrectPadForThisChipset (GpioPad)) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Incorrect GpioPad (0x%08x) used on this chipset!\n", GpioPad)); + goto Error; + } + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Check if legal pin number + // + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad); + PadNumber = GpioGetPadNumberFromGpioPad (GpioPad); + if (PadNumber >= GpioGroupInfo[GroupIndex].PadPerGroup) { + DEBUG ((DEBUG_ERROR, "GPIO ERROR: Pin number (%d) exceeds range of group (max: %d)\n", + PadNumber, + GpioGroupInfo[GroupIndex].PadPerGroup)); + goto Error; + } + + return TRUE; +Error: + ASSERT (FALSE); + return FALSE; +} + +/** + This procedure will read GPIO Pad Configuration register + + @param[in] GpioPad GPIO pad + @param[in] DwReg Choose PADCFG register: 0:DW0, 1:DW1 + + @retval PadCfgRegValue PADCFG_DWx value +**/ +UINT32 +GpioReadPadCfgReg ( + IN GPIO_PAD GpioPad, + IN UINT8 DwReg + ) +{ + UINT32 PadCfgReg; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 GroupIndex; + + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad); + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Create Pad Configuration register offset + // + PadCfgReg = GpioGetGpioPadCfgAddressFromGpioPad (GpioPad, DwReg); + return GpioRegisterAccessRead32 (&GpioGroupInfo[GroupIndex], PadCfgReg); +} + + +/** + This procedure will calculate PADCFG register value based on GpioConfig data + For physical/local/hard (not virtual) GPIO pads + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfigHardGpio ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ) +{ + // + // Configure how interrupt is triggered (RxEvCfg) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_LVL_EDG); + PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_TYPE_MASK) >> (N_GPIO_INT_CONFIG_INT_TYPE_BIT_POS + 1)) << N_GPIO_PCR_RX_LVL_EDG); + + // + // Configure interrupt generation (GPIRoutIOxAPIC/SCI/SMI/NMI) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS) == GpioHardwareDefault) ? 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)); + PadCfgDwReg[0] |= (((GpioConfig->InterruptConfig & B_GPIO_INT_CONFIG_INT_SOURCE_MASK) >> (N_GPIO_INT_CONFIG_INT_SOURCE_BIT_POS + 1)) << N_GPIO_PCR_RX_NMI_ROUTE); + + // + // Configure GPIO direction (GPIORxDis and GPIOTxDis) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> N_GPIO_DIRECTION_DIR_BIT_POS) == GpioHardwareDefault) ? 0x0 : (B_GPIO_PCR_RXDIS | B_GPIO_PCR_TXDIS)); + PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_DIR_MASK) >> (N_GPIO_DIRECTION_DIR_BIT_POS + 1)) << N_GPIO_PCR_TXDIS); + + // + // Configure GPIO input inversion (RXINV) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> N_GPIO_DIRECTION_INV_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RXINV); + PadCfgDwReg[0] |= (((GpioConfig->Direction & B_GPIO_DIRECTION_INV_MASK) >> (N_GPIO_DIRECTION_INV_BIT_POS + 1)) << N_GPIO_PCR_RXINV); + + // + // Configure GPIO output state (GPIOTxState) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> N_GPIO_OUTPUT_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TX_STATE); + PadCfgDwReg[0] |= (((GpioConfig->OutputState & B_GPIO_OUTPUT_MASK) >> (N_GPIO_OUTPUT_BIT_POS + 1)) << N_GPIO_PCR_TX_STATE); + + // + // Configure GPIO RX raw override to '1' (RXRAW1) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_RX_RAW1); + PadCfgDwReg[0] |= (((GpioConfig->OtherSettings & B_GPIO_OTHER_CONFIG_RXRAW_MASK) >> (N_GPIO_OTHER_CONFIG_RXRAW_BIT_POS + 1)) << N_GPIO_PCR_RX_RAW1); + + // + // Configure GPIO Pad Mode (PMode) + // + PadCfgDwRegMask[0] |= ((((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> N_GPIO_PAD_MODE_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_PAD_MODE); + PadCfgDwReg[0] |= (((GpioConfig->PadMode & B_GPIO_PAD_MODE_MASK) >> (N_GPIO_PAD_MODE_BIT_POS + 1)) << N_GPIO_PCR_PAD_MODE); + + // + // Configure GPIO termination (Term) + // + PadCfgDwRegMask[1] |= ((((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS) == GpioHardwareDefault) ? 0x0 : B_GPIO_PCR_TERM); + PadCfgDwReg[1] |= (((GpioConfig->ElectricalConfig & B_GPIO_ELECTRICAL_CONFIG_TERMINATION_MASK) >> (N_GPIO_ELECTRICAL_CONFIG_TERMINATION_BIT_POS + 1)) << N_GPIO_PCR_TERM); + + return EFI_SUCCESS; +} + diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c new file mode 100644 index 0000000000..3d16fd2acd --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibPch.c @@ -0,0 +1,172 @@ +/** @file + This file contains hard/physical/local (not virtual) GPIO information + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Uefi/UefiBaseType.h> +#include <Library/GpioLib.h> +#include <Library/GpioPrivateLib.h> +#include <Library/GpioNativeLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/PchSbiAccessLib.h> +#include <Register/GpioRegs.h> +#include "GpioNativePrivateLibInternal.h" + +/** + This procedure calculates Pad Configuration Register DW offset + + @param[in] GpioPad GPIO pad + @param[in] DwReg Index of the configuration register + + @retval DW Register offset +**/ +UINT32 +GpioGetGpioPadCfgAddressFromGpioPad ( + IN GPIO_PAD GpioPad, + IN UINT32 DwReg + ) +{ + UINT32 PadCfgRegAddress; + CONST GPIO_GROUP_INFO *GpioGroupInfo; + UINT32 GpioGroupInfoLength; + UINT32 GroupIndex; + UINT32 PadNumber; + + GroupIndex = GpioGetGroupIndexFromGpioPad (GpioPad); + PadNumber = GpioGetPadNumberFromGpioPad (GpioPad); + + GpioGroupInfo = GpioGetGroupInfoTable (&GpioGroupInfoLength); + + // + // Create Pad Configuration register offset + // + PadCfgRegAddress = GpioGroupInfo[GroupIndex].PadCfgOffset + DwReg * 4 + S_GPIO_PCR_PADCFG * PadNumber; + + return PadCfgRegAddress; +} + +/** + This procedure reads GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + + @retval Register value or "F"s in case of errors +**/ +UINT32 +GpioRegisterAccessRead32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register + ) +{ + return MmioRead32 (PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register)); +} + +/** + This procedure writes GPIO register + + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] Register Register offset + @param[in] AndValue And value + @param[in] OrValue Or value + + @retval EFI_SUCCESS Operation completed successfully +**/ +EFI_STATUS +GpioRegisterAccessAndThenOr32 ( + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 Register, + IN UINT32 AndValue, + IN UINT32 OrValue + ) +{ + MmioAndThenOr32 ( + PCH_PCR_ADDRESS (GpioGroupInfo->Community, Register), + AndValue, + OrValue + ); + return EFI_SUCCESS; +} + +/** + This procedure will calculate PADCFG register value based on GpioConfig data + + @param[in] GpioPad GPIO Pad + @param[in] GpioConfig GPIO Configuration data + @param[out] PadCfgDwReg PADCFG DWx register value + @param[out] PadCfgDwRegMask Mask with PADCFG DWx register bits to be modified + + @retval Status +**/ +EFI_STATUS +GpioPadCfgRegValueFromGpioConfig ( + IN GPIO_PAD GpioPad, + IN CONST GPIO_CONFIG *GpioConfig, + OUT UINT32 *PadCfgDwReg, + OUT UINT32 *PadCfgDwRegMask + ) +{ + return GpioPadCfgRegValueFromGpioConfigHardGpio (GpioPad, GpioConfig, PadCfgDwReg, PadCfgDwRegMask); +} + +/** + This procedure will write GPIO Lock/LockTx register + - For PCH SBI message is used. + + @param[in] RegValue GPIO register (Lock or LockTx) value + @param[in] RegOffset GPIO register (Lock or LockTx) base offset + @param[in] DwNum Register number for current group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] GpioGroupInfo Pointer to GPIO group table info + @param[in] GroupIndex GPIO group index in the GpioGroupInfo table + + @retval EFI_SUCCESS The function completed successfully + EFI_UNSUPPORTED Feature is not supported for this group or pad +**/ +EFI_STATUS +GpioInternalWriteLockRegister ( + IN UINT32 RegValue, + IN UINT32 RegOffset, + IN UINT32 DwNum, + IN CONST GPIO_GROUP_INFO *GpioGroupInfo, + IN UINT32 GroupIndex + ) +{ + EFI_STATUS Status; + PCH_SBI_OPCODE Opcode; + UINT8 Response; + + // + // If there are more then 32 pads per group then certain + // group information would be split into more then one DWord register. + // PadConfigLock and OutputLock registers when used for group containing more than 32 pads + // are not placed in a continuous way, e.g: + // 0x0 - PadConfigLock_DW0 + // 0x4 - OutputLock_DW0 + // 0x8 - PadConfigLock_DW1 + // 0xC - OutputLock_DW1 + // + RegOffset += DwNum * 0x8; + + if (IsGpioLockOpcodeSupported ()) { + Opcode = GpioLockUnlock; + } else { + Opcode = PrivateControlWrite; + } + + Status = PchSbiExecutionEx ( + GpioGroupInfo[GroupIndex].Community, + RegOffset, + Opcode, + FALSE, + 0x000F, + 0x0000, + 0x0000, + &RegValue, + &Response + ); + ASSERT_EFI_ERROR (Status); + return Status; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c new file mode 100644 index 0000000000..1348643553 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/GpioPrivateLibVer2.c @@ -0,0 +1,81 @@ +/** @file + This file contains VER2 specific GPIO information + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Uefi/UefiBaseType.h> +#include <Library/DebugLib.h> +#include <Library/PchInfoLib.h> +#include <Library/GpioLib.h> +#include <Library/GpioNativeLib.h> +#include <Library/GpioNativePads.h> +#include <Library/GpioPrivateLib.h> +#include <Library/GpioHelpersLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/IoLib.h> +#include <Register/GpioRegsVer2.h> +#include <Register/PchPcrRegs.h> +#include <Register/GpioRegs.h> +#include <Pins/GpioPinsVer2Lp.h> +#include <GpioNativePrivateLibInternal.h> +#include <Library/PcdLib.h> +GLOBAL_REMOVE_IF_UNREFERENCED GPIO_GROUP_INFO mPchLpGpioGroupInfo[] = { + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PAD_OWN, R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_B_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_B_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_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 + {PID_GPIOCOM0, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM0, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_A_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM5, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_R_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM5, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM2, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPD_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_S_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_H_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM1, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PAD_OWN, R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_D_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_D_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_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 + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM1, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PAD_OWN, R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_C_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_C_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_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 + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_F_PAD_OWN, R_GPIO_VER2_PCH_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_FOR_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 + {PID_GPIOCOM4, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, NO_REGISTER_FOR_PROPERTY, 0}, + {PID_GPIOCOM4, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PAD_OWN, R_GPIO_VER2_PCH_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_PCH_LP_GPIO_PCR_GPP_E_SMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_SMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_STS, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_NMI_EN, R_GPIO_VER2_PCH_LP_GPIO_PCR_GPP_E_PADCFGLOCK, R_GPIO_VER2_PCH_LP_GPIO_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 +}; + +/** + This procedure will retrieve address and length of GPIO info table + + @param[out] GpioGroupInfoTableLength Length of GPIO group table + + @retval Pointer to GPIO group table + +**/ +CONST GPIO_GROUP_INFO* +GpioGetGroupInfoTable ( + OUT UINT32 *GpioGroupInfoTableLength + ) +{ + *GpioGroupInfoTableLength = ARRAY_SIZE (mPchLpGpioGroupInfo); + return mPchLpGpioGroupInfo; +} + +/** + Get GPIO Chipset ID specific to PCH generation and series +**/ +UINT32 +GpioGetThisChipsetId ( + VOID + ) +{ + return GPIO_VER2_LP_CHIPSET_ID; +} + +/** + Check if 0x13 opcode supported for writing to GPIO lock unlock register + + @retval TRUE It's supported + @retval FALSE It's not supported +**/ +BOOLEAN +IsGpioLockOpcodeSupported ( + VOID + ) +{ + return TRUE; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf new file mode 100644 index 0000000000..2e9a6b7336 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiDxeSmmGpioPrivateLib/PeiDxeSmmGpioPrivateLibVer2.inf @@ -0,0 +1,40 @@ +## @file +# Component description file for the PeiDxeSmmGpioPrivateLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiDxeSmmGpioPrivateLibVer2 +FILE_GUID = 680A81B0-A087-4687-B5B4-146DA30042D6 +VERSION_STRING = 1.0 +MODULE_TYPE = BASE +LIBRARY_CLASS = GpioPrivateLib +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + + +[LibraryClasses] + BaseLib + IoLib + DebugLib + PmcLib + PchInfoLib + GpioLib + GpioHelpersLib + + +[Packages] + MdePkg/MdePkg.dec + AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] + GpioPrivateLib.c + GpioPrivateLibVer2.c + GpioPrivateLibPch.c diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c new file mode 100644 index 0000000000..9d47e6bfd5 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.c @@ -0,0 +1,218 @@ +/** @file + This file contains routines for PEI GPIO Helpers Lib + + Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ +#include <Library/HobLib.h> +#include <Base.h> +#include <Uefi/UefiBaseType.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/GpioNativeLib.h> +#include <Library/GpioPrivateLib.h> +#include <Library/GpioHelpersLib.h> +#include <Library/PeiServicesLib.h> +#include <Library/ConfigBlockLib.h> +#include <Ppi/SiPolicy.h> + +extern EFI_GUID gGpioLibUnlockHobGuid; + +// +// GPIO Lock HOB +// Stores information on GPIO pads that should be left unlocked +// +typedef struct { + // + // GPIO PadConfig unlock data + // + UINT32 PadConfig; + // + // GPIO Output unlock data + // + UINT32 OutputState; +} GPIO_UNLOCK_HOB_DATA; + +/** + This procedure will get index of GPIO Unlock HOB structure for selected GroupIndex and DwNum. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + + @retval GpioUnlockHobIndex +**/ +STATIC +UINT32 +GpioUnlockDataIndex ( + IN UINT32 GroupIndex, + IN UINT32 DwNum + ) +{ + UINT32 GpioUnlockDataIndex; + UINT32 Index; + + GpioUnlockDataIndex = 0; + + for (Index = 0; Index < GroupIndex; Index++) { + GpioUnlockDataIndex += GPIO_GET_DW_NUM (GpioGetPadPerGroup (GpioGetGroupFromGroupIndex (Index))) + 1; + } + + GpioUnlockDataIndex += DwNum; + return GpioUnlockDataIndex; +} + +/** + This procedure will create GPIO HOB for storing unlock data + + @retval Pointer to GPIO Unlock data structure +**/ +STATIC +GPIO_UNLOCK_HOB_DATA* +GpioCreateUnlockData ( + VOID + ) +{ + VOID *HobData; + GPIO_GROUP Group; + GPIO_GROUP GroupMin; + GPIO_GROUP GroupMax; + UINT32 GpioUnlockDataRecords; + + GroupMin = GpioGetLowestGroup (); + GroupMax = GpioGetHighestGroup (); + GpioUnlockDataRecords = 0; + + for (Group = GroupMin; Group <= GroupMax; Group++) { + GpioUnlockDataRecords += GPIO_GET_DW_NUM (GpioGetPadPerGroup (Group)) + 1; + } + + HobData = BuildGuidHob (&gGpioLibUnlockHobGuid, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA)); + if (HobData == NULL) { + return NULL; + } + + ZeroMem (HobData, GpioUnlockDataRecords * sizeof (GPIO_UNLOCK_HOB_DATA)); + + return (GPIO_UNLOCK_HOB_DATA*)HobData; +} + +/** + This procedure will Get GPIO Unlock data structure for storing unlock data. + If HOB doesn't exist it will be created. + + @param[out] GpioUnlockData pointer to GPIO Unlock data structure + + @retval Length number of GPIO unlock data records +**/ +STATIC +UINT32 +GpioGetUnlockData ( + GPIO_UNLOCK_HOB_DATA **GpioUnlockData + ) +{ + VOID *Hob; + + Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid); + if (Hob == NULL) { + // + // It is the first time this function is used so create the HOB + // + *GpioUnlockData = GpioCreateUnlockData (); + if (*GpioUnlockData == NULL) { + return 0; + } + Hob = GetFirstGuidHob (&gGpioLibUnlockHobGuid); + } else { + *GpioUnlockData = (GPIO_UNLOCK_HOB_DATA*) GET_GUID_HOB_DATA (Hob); + } + return GET_GUID_HOB_DATA_SIZE (Hob) / sizeof (GPIO_UNLOCK_HOB_DATA); +} + +/** + This procedure stores GPIO group data about pads which PadConfig needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockPadConfigData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ) +{ + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; + UINT32 Length; + UINT32 Index; + + if (UnlockedPads == 0) { + // + // No pads to be left unlocked + // + return EFI_SUCCESS; + } + + Length = GpioGetUnlockData (&GpioUnlockData); + if (Length == 0) { + return EFI_NOT_FOUND; + } + + Index = GpioUnlockDataIndex (GroupIndex, DwNum); + if (Index >= Length) { + return EFI_INVALID_PARAMETER; + } + + GpioUnlockData[Index].PadConfig |= UnlockedPads; + return EFI_SUCCESS; +} + +/** + This procedure stores GPIO group data about pads which Output state needs to be unlocked. + + @param[in] GroupIndex GPIO group index + @param[in] DwNum DWORD index for a group. + For group which has less then 32 pads per group DwNum must be 0. + @param[in] UnlockedPads DWORD bitmask for pads which are going to be left unlocked + Bit position - PadNumber + Bit value - 0: Skip, 1: Leave unlocked + @retval Status +**/ +EFI_STATUS +GpioStoreGroupDwUnlockOutputData ( + IN UINT32 GroupIndex, + IN UINT32 DwNum, + IN UINT32 UnlockedPads + ) +{ + GPIO_UNLOCK_HOB_DATA *GpioUnlockData; + UINT32 Length; + UINT32 Index; + + if (UnlockedPads == 0) { + // + // No pads to be left unlocked + // + return EFI_SUCCESS; + } + + Length = GpioGetUnlockData (&GpioUnlockData); + if (Length == 0) { + return EFI_NOT_FOUND; + } + + Index = GpioUnlockDataIndex (GroupIndex, DwNum); + if (Index >= Length) { + return EFI_INVALID_PARAMETER; + } + + GpioUnlockData[Index].OutputState |= UnlockedPads; + return EFI_SUCCESS; +} diff --git a/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf new file mode 100644 index 0000000000..c1886b22f9 --- /dev/null +++ b/Silicon/Intel/AlderlakeSiliconPkg/IpBlock/Gpio/LibraryPrivate/PeiGpioHelpersLib/PeiGpioHelpersLib.inf @@ -0,0 +1,46 @@ +## @file +# Component description file for the PeiGpioHelpersLib +# +# Copyright (c) 2022, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +## + + +[Defines] +INF_VERSION = 0x00010017 +BASE_NAME = PeiGpioHelpersLib +FILE_GUID = 1838E1E7-3CC4-4A74-90D9-B421EF2A579F +VERSION_STRING = 1.0 +MODULE_TYPE = PEIM +LIBRARY_CLASS = GpioHelpersLib +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + + +[LibraryClasses] +BaseLib +IoLib +DebugLib +HobLib +GpioLib +ConfigBlockLib +PeiServicesLib + + +[Packages] +MdePkg/MdePkg.dec +AlderlakeSiliconPkg/SiPkg.dec + + +[Sources] +PeiGpioHelpersLib.c + + +[Guids] +gGpioLibUnlockHobGuid + +[Ppis] +gSiPreMemPolicyPpiGuid -- 2.36.1.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#108614): https://edk2.groups.io/g/devel/message/108614 Mute This Topic: https://groups.io/mt/101347727/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-