[edk2-devel] [Patch V2 24/40] TigerlakeSiliconPkg/IpBlock: Add Pmc component

Heng Luo heng.luo at intel.com
Thu Feb 4 08:49:03 UTC 2021


REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3171

Adds the following files:
  * IpBlock/Pmc/IncludePrivate
  * IpBlock/Pmc/Library
  * IpBlock/Pmc/LibraryPrivate

Cc: Sai Chaganty <rangasai.v.chaganty at intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
Signed-off-by: Heng Luo <heng.luo at intel.com>
---
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h                                 | 120 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h                                  |  52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf                            |  42 ++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c                                       | 545 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf   |  39 +++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf |  40 ++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c                  | 166 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c            | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 1126 insertions(+)

diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h
new file mode 100644
index 0000000000..0f2f251d57
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Library/PmcPrivateLib.h
@@ -0,0 +1,120 @@
+/** @file
+  Header file for private PmcLib.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PMC_PRIVATE_LIB_H_
+#define _PMC_PRIVATE_LIB_H_
+
+#include <Library/PmcLib.h>
+#include "Register/PmcRegs.h"
+
+/**
+  This function checks if GbE device is supported (not disabled by fuse)
+
+  @retval GbE support state
+**/
+BOOLEAN
+PmcIsGbeSupported (
+  VOID
+  );
+
+/**
+  This function checks if LAN wake from DeepSx is enabled
+
+  @retval Lan Wake state
+**/
+BOOLEAN
+PmcIsLanDeepSxWakeEnabled (
+  VOID
+  );
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function sets eSPI SMI Lock
+  @attention This function must be called after eSPI SMI generation has been enabled.
+    This setting is required in all boot modes and before EndOfDxe.
+    If set value will be restored upon S3 resume by bootscript.
+**/
+VOID
+PmcLockEspiSmiWithS3BootScript (
+  VOID
+  );
+
+/**
+  This function checks if eSPI SMI Lock is set
+
+  @retval eSPI SMI Lock state
+**/
+BOOLEAN
+PmcIsEspiSmiLockSet (
+  VOID
+  );
+
+typedef enum {
+  PmcSwSmiRate1p5ms = 0,
+  PmcSwSmiRate16ms,
+  PmcSwSmiRate32ms,
+  PmcSwSmiRate64ms
+} PMC_SWSMI_RATE;
+
+/**
+  This function sets SW SMI Rate.
+
+  @param[in] SwSmiRate        Refer to PMC_SWSMI_RATE for possible values
+**/
+VOID
+PmcSetSwSmiRate (
+  IN PMC_SWSMI_RATE          SwSmiRate
+  );
+
+typedef enum {
+  PmcPeriodicSmiRate8s = 0,
+  PmcPeriodicSmiRate16s,
+  PmcPeriodicSmiRate32s,
+  PmcPeriodicSmiRate64s
+} PMC_PERIODIC_SMI_RATE;
+
+/**
+  This function sets Periodic SMI Rate.
+
+  @param[in] PeriodicSmiRate        Refer to PMC_PERIODIC_SMI_RATE for possible values
+**/
+VOID
+PmcSetPeriodicSmiRate (
+  IN PMC_PERIODIC_SMI_RATE    PeriodicSmiRate
+  );
+
+/**
+  This function reads Power Button Level
+
+  @retval State of PWRBTN# signal (0: Low, 1: High)
+**/
+UINT8
+PmcGetPwrBtnLevel (
+  VOID
+  );
+
+/**
+  This function gets Group to GPE0 configuration
+
+  @param[out] GpeDw0Value       GPIO Group to GPE_DW0 assignment
+  @param[out] GpeDw1Value       GPIO Group to GPE_DW1 assignment
+  @param[out] GpeDw2Value       GPIO Group to GPE_DW2 assignment
+**/
+VOID
+PmcGetGpioGpe (
+  OUT UINT32    *GpeDw0Value,
+  OUT UINT32    *GpeDw1Value,
+  OUT UINT32    *GpeDw2Value
+  );
+
+#endif // _PMC_PRIVATE_LIB_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h
new file mode 100644
index 0000000000..986173dd7d
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/IncludePrivate/Register/PmcRegsVer2.h
@@ -0,0 +1,52 @@
+/** @file
+  Register names for Ver2 PCH PMC device
+
+  Conventions:
+
+  - Register definition format:
+    Prefix_[GenerationName]_[ComponentName]_SubsystemName_RegisterSpace_RegisterName
+  - Prefix:
+    Definitions beginning with "R_" are registers
+    Definitions beginning with "B_" are bits within registers
+    Definitions beginning with "V_" are meaningful values within the bits
+    Definitions beginning with "S_" are register size
+    Definitions beginning with "N_" are the bit position
+  - [GenerationName]:
+    Three letter acronym of the generation is used (e.g. SKL,KBL,CNL etc.).
+    Register name without GenerationName applies to all generations.
+  - [ComponentName]:
+    This field indicates the component name that the register belongs to (e.g. PCH, SA etc.)
+    Register name without ComponentName applies to all components.
+    Register that is specific to -LP denoted by "_PCH_LP_" in component name.
+  - SubsystemName:
+    This field indicates the subsystem name of the component that the register belongs to
+    (e.g. PCIE, USB, SATA, GPIO, PMC etc.).
+  - RegisterSpace:
+    MEM - MMIO space register of subsystem.
+    IO  - IO space register of subsystem.
+    PCR - Private configuration register of subsystem.
+    CFG - PCI configuration space register of subsystem.
+  - RegisterName:
+    Full register name.
+
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _PCH_REGS_PMC_TGL_H_
+#define _PCH_REGS_PMC_TGL_H_
+
+//
+// PWRM Registers
+//
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_B     0x0
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_A     0x2
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_R     0x3
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPD       0x4
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_S     0x5
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_H     0x6
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_D     0x7
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_F     0xA
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_C     0xB
+#define V_TGL_PCH_LP_PMC_PWRM_GPIO_CFG_GPP_E     0xC
+
+#endif // _PCH_REGS_PMC_TGL_H_
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
new file mode 100644
index 0000000000..eba6db767c
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PeiDxeSmmPmcLib.inf
@@ -0,0 +1,42 @@
+## @file
+# PEI/DXE/SMM PCH PMC Lib.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPmcLib
+FILE_GUID = 9D60C364-5086-41E3-BC9D-C62AB7233DBF
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PmcLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PchCycleDecodingLib
+PchPcrLib
+PchInfoLib
+BaseMemoryLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+gSiPkgTokenSpaceGuid.PcdTcoBaseAddress
+
+[Sources]
+PmcLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c
new file mode 100644
index 0000000000..78e596b268
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/Library/PeiDxeSmmPmcLib/PmcLib.c
@@ -0,0 +1,545 @@
+/** @file
+  PCH PMC Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, 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/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <PchReservedResources.h>
+#include <Register/PmcRegs.h>
+#include <Register/PchRegs.h>
+
+/**
+  Get PCH ACPI base address.
+
+  @retval Address                   Address of PWRM base address.
+**/
+UINT16
+PmcGetAcpiBase (
+  VOID
+  )
+{
+  return PcdGet16 (PcdAcpiBaseAddress);
+}
+
+/**
+  Get PCH PWRM base address.
+
+  @retval Address                   Address of PWRM base address.
+**/
+UINT32
+PmcGetPwrmBase (
+  VOID
+  )
+{
+  return PCH_PWRM_BASE_ADDRESS;
+}
+
+/**
+  This function enables Power Button SMI
+**/
+VOID
+PmcEnablePowerButtonSmi (
+  VOID
+  )
+{
+  IoOr16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, B_ACPI_IO_PM1_EN_PWRBTN);
+}
+
+/**
+  This function disables Power Button SMI
+**/
+VOID
+PmcDisablePowerButtonSmi (
+  VOID
+  )
+{
+  IoAnd16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_EN, (UINT16)~B_ACPI_IO_PM1_EN_PWRBTN);
+}
+
+/**
+  This function reads PM Timer Count driven by 3.579545 MHz clock
+
+  @retval PM Timer Count
+**/
+UINT32
+PmcGetTimerCount (
+  VOID
+  )
+{
+  return IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_PM1_TMR) & B_ACPI_IO_PM1_TMR_VAL;
+}
+
+/**
+  Get Sleep Type that platform has waken from
+
+  @retval SleepType                Sleep Type
+**/
+PMC_SLEEP_STATE
+PmcGetSleepTypeAfterWake (
+  VOID
+  )
+{
+  UINT16  AcpiBase;
+  UINT32  PmconA;
+
+  AcpiBase = PmcGetAcpiBase ();
+  PmconA   = MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A);
+
+  DEBUG ((DEBUG_INFO, "PWRM_PMCON_A = 0x%x\n", PmconA));
+
+  //
+  // If Global Reset Status, Power Failure. Host Reset Status bits are set, return S5 State
+  //
+  if ((PmconA & (B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS | B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS)) != 0) {
+    return PmcNotASleepState;
+  }
+
+  if (IoRead16 (AcpiBase + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_WAK) {
+    switch (IoRead16 (AcpiBase + R_ACPI_IO_PM1_CNT) & B_ACPI_IO_PM1_CNT_SLP_TYP) {
+      case V_ACPI_IO_PM1_CNT_S0:
+        return PmcInS0State;
+
+      case V_ACPI_IO_PM1_CNT_S1:
+        return PmcS1SleepState;
+
+      case V_ACPI_IO_PM1_CNT_S3:
+        return PmcS3SleepState;
+
+      case V_ACPI_IO_PM1_CNT_S4:
+        return PmcS4SleepState;
+
+      case V_ACPI_IO_PM1_CNT_S5:
+        return PmcS5SleepState;
+
+      default:
+        ASSERT (FALSE);
+        return PmcUndefinedState;
+    }
+  } else {
+    return PmcNotASleepState;
+  }
+}
+
+/**
+  Clear PMC Wake Status
+**/
+VOID
+PmcClearWakeStatus (
+  VOID
+  )
+{
+  IoWrite16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_WAK);
+}
+
+/**
+  Configure sleep state
+
+  @param[in] SleepState         S0/S1/S3/S4/S5, refer to PMC_SLEEP_STATE
+**/
+VOID
+PmcSetSleepState (
+  PMC_SLEEP_STATE  SleepState
+  )
+{
+  UINT16  Data16;
+
+  switch (SleepState) {
+    case PmcInS0State:
+      Data16 = V_ACPI_IO_PM1_CNT_S0;
+      break;
+
+    case PmcS1SleepState:
+      Data16 = V_ACPI_IO_PM1_CNT_S1;
+      break;
+
+    case PmcS3SleepState:
+      Data16 = V_ACPI_IO_PM1_CNT_S3;
+      break;
+
+    case PmcS4SleepState:
+      Data16 = V_ACPI_IO_PM1_CNT_S4;
+      break;
+
+    case PmcS5SleepState:
+      Data16 = V_ACPI_IO_PM1_CNT_S5;
+      break;
+
+    default:
+      ASSERT (FALSE);
+      return;
+
+  }
+  IoAndThenOr16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_CNT, (UINT16) ~B_ACPI_IO_PM1_CNT_SLP_TYP, Data16);
+}
+
+/**
+  Check if platform boots after shutdown caused by power button override event
+
+  @retval  TRUE   Power Button Override occurred in last system boot
+  @retval  FALSE  Power Button Override didn't occur
+**/
+BOOLEAN
+PmcIsPowerButtonOverrideDetected (
+  VOID
+  )
+{
+  return ((IoRead16 (PmcGetAcpiBase () + R_ACPI_IO_PM1_STS) & B_ACPI_IO_PM1_STS_PRBTNOR) != 0);
+}
+
+/**
+  This function sets tPCH25 timing
+
+  @param[in] TimingValue       tPCH25 timing value (10us, 100us, 1ms, 10ms)
+**/
+VOID
+PmcSetTPch25Timing (
+  IN PMC_TPCH25_TIMING    TimingValue
+  )
+{
+  ASSERT (TimingValue <= PmcTPch25_10ms);
+
+  MmioAndThenOr32 (
+    (UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_CFG),
+    (UINT32)~(B_PMC_PWRM_CFG_TIMING_TPCH25),
+    TimingValue
+    );
+}
+
+/**
+  This function checks if RTC Power Failure occurred by
+  reading RTC_PWR_FLR bit
+
+  @retval RTC Power Failure state: TRUE  - Battery is always present.
+                                   FALSE - CMOS is cleared.
+**/
+BOOLEAN
+PmcIsRtcBatteryGood (
+  VOID
+  )
+{
+  return ((MmioRead8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B) & B_PMC_PWRM_GEN_PMCON_B_RTC_PWR_STS) == 0);
+}
+
+/**
+  This function checks if Power Failure occurred by
+  reading PWR_FLR bit
+
+  @retval Power Failure state
+**/
+BOOLEAN
+PmcIsPowerFailureDetected (
+  VOID
+  )
+{
+  return ((MmioRead16 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A) & B_PMC_PWRM_GEN_PMCON_A_PWR_FLR) != 0);
+}
+
+/**
+  This function checks if Power Failure occurred by
+  reading SUS_PWR_FLR bit
+
+  @retval SUS Power Failure state
+**/
+BOOLEAN
+PmcIsSusPowerFailureDetected (
+  VOID
+  )
+{
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A) & B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR) != 0);
+}
+
+/**
+  This function clears Power Failure status (PWR_FLR)
+**/
+VOID
+PmcClearPowerFailureStatus (
+  VOID
+  )
+{
+  //
+  // Write 1 to clear PWR_FLR
+  // Avoid clearing other W1C bits
+  //
+  MmioAndThenOr8 (
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1,
+    (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8),
+    B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8
+    );
+}
+
+/**
+  This function clears Global Reset status (GBL_RST_STS)
+**/
+VOID
+PmcClearGlobalResetStatus (
+  VOID
+  )
+{
+  //
+  // Write 1 to clear GBL_RST_STS
+  // Avoid clearing other W1C bits
+  //
+  MmioAndThenOr8 (
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 3,
+    (UINT8) ~0,
+    B_PMC_PWRM_GEN_PMCON_A_GBL_RST_STS >> 24
+    );
+}
+
+/**
+  This function clears Host Reset status (HOST_RST_STS)
+**/
+VOID
+PmcClearHostResetStatus (
+  VOID
+  )
+{
+  //
+  // Write 1 to clear HOST_RST_STS
+  // Avoid clearing other W1C bits
+  //
+  MmioAndThenOr8 (
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1,
+    (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_PWR_FLR >> 8),
+    B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS >> 8
+    );
+}
+
+/**
+  This function clears SUS Power Failure status (SUS_PWR_FLR)
+**/
+VOID
+PmcClearSusPowerFailureStatus (
+  VOID
+  )
+{
+  //
+  // BIOS clears this bit by writing a '1' to it.
+  // Take care of other fields, so we don't clear them accidentally.
+  //
+  MmioAndThenOr8 (
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 2,
+    (UINT8) ~(B_PMC_PWRM_GEN_PMCON_A_MS4V >> 16),
+    B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR >> 16
+    );
+}
+
+/**
+  This function sets state to which platform will get after power is reapplied
+
+  @param[in] PowerStateAfterG3          0: S0 state (boot)
+                                        1: S5/S4 State
+**/
+VOID
+PmcSetPlatformStateAfterPowerFailure (
+  IN UINT8 PowerStateAfterG3
+  )
+{
+  UINT32                PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  if (PowerStateAfterG3) {
+    MmioOr8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN);
+  } else {
+    MmioAnd8 (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A, (UINT8)~B_PMC_PWRM_GEN_PMCON_A_AFTERG3_EN);
+  }
+}
+
+/**
+  This function will set the DISB - DRAM Initialization Scratchpad Bit.
+**/
+VOID
+PmcSetDramInitScratchpad (
+  VOID
+  )
+{
+  //
+  // Set B_CNL_PCH_PWRM_GEN_PMCON_A_DISB.
+  // NOTE: Byte access and not clear BIT18 and BIT16 (W1C bits)
+  //
+  MmioAndThenOr8 (
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 2,
+    (UINT8) ~((B_PMC_PWRM_GEN_PMCON_A_MS4V | B_PMC_PWRM_GEN_PMCON_A_SUS_PWR_FLR) >> 16),
+    B_PMC_PWRM_GEN_PMCON_A_DISB >> 16
+    );
+}
+
+/**
+  Check global SMI enable is set
+
+  @retval TRUE  Global SMI enable is set
+          FALSE Global SMI enable is not set
+**/
+BOOLEAN
+PmcIsGblSmiEn (
+  VOID
+  )
+{
+  return !!(IoRead32 (PmcGetAcpiBase () + R_ACPI_IO_SMI_EN) & B_ACPI_IO_SMI_EN_GBL_SMI);
+}
+
+/**
+  This function checks if SMI Lock is set
+
+  @retval SMI Lock state
+**/
+BOOLEAN
+PmcIsSmiLockSet (
+  VOID
+  )
+{
+  return ((MmioRead8 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B)) & B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK) != 0);
+}
+
+/**
+  This function checks if Debug Mode is locked
+
+  @retval Debug Mode Lock state
+**/
+BOOLEAN
+PmcIsDebugModeLocked (
+  VOID
+  )
+{
+  //
+  // Get lock info from PWRMBASE + PM_CFG
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_CFG) & B_PMC_PWRM_CFG_DBG_MODE_LOCK) != 0);
+}
+
+/**
+  Check TCO second timeout status.
+
+  @retval  TRUE   TCO reboot happened.
+  @retval  FALSE  TCO reboot didn't happen.
+**/
+BOOLEAN
+TcoSecondToHappened (
+  VOID
+  )
+{
+  ///
+  /// Read the Second TO status bit
+  ///
+  if ((IoRead8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS) & R_TCO_IO_TCO2_STS) != 0) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  This function clears the Second TO status bit
+**/
+VOID
+TcoClearSecondToStatus (
+  VOID
+  )
+{
+  IoWrite8 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO2_STS, B_TCO_IO_TCO2_STS_SECOND_TO);
+}
+
+/**
+  Check TCO SMI ENABLE is locked
+
+  @retval TRUE  TCO SMI ENABLE is locked
+          FALSE TCO SMI ENABLE is not locked
+**/
+BOOLEAN
+TcoIsSmiLock (
+  VOID
+  )
+{
+  return !!(IoRead16 (PcdGet16 (PcdTcoBaseAddress) + R_TCO_IO_TCO1_CNT) & B_TCO_IO_TCO1_CNT_LOCK);
+}
+
+/**
+   Check if user wants to turn off in PEI phase and power it off
+   CAUTION: this function will potentially turn off your system
+**/
+VOID
+CheckPowerOffNow (
+  VOID
+  )
+{
+  UINT16  ABase;
+  UINT16  Pm1Sts;
+
+  ABase = PmcGetAcpiBase ();
+
+  //
+  // Read and check the ACPI registers
+  //
+  Pm1Sts = IoRead16 (ABase + R_ACPI_IO_PM1_STS);
+
+  DEBUG ((DEBUG_ERROR, "CheckPowerOffNow ()- Pm1Sts= 0x%04x\n", Pm1Sts));
+
+  if ((Pm1Sts & B_ACPI_IO_PM1_STS_PWRBTN) != 0) {
+    IoWrite16 (ABase + R_ACPI_IO_PM1_STS, B_ACPI_IO_PM1_STS_PWRBTN);
+    IoWrite16 (ABase + R_ACPI_IO_PM1_CNT, V_ACPI_IO_PM1_CNT_S5);
+    IoWrite16 (ABase + R_ACPI_IO_PM1_CNT, V_ACPI_IO_PM1_CNT_S5 | B_ACPI_IO_PM1_CNT_SLP_EN);
+  }
+}
+
+/**
+ Clear any SMI status or wake status.
+**/
+VOID
+ClearSmiAndWake (
+  VOID
+  )
+{
+  UINT16              ABase;
+  UINT16              Pm1Sts;
+
+  ABase = PmcGetAcpiBase ();
+
+  //
+  // Clear any SMI or wake state from the boot
+  //
+  Pm1Sts = B_ACPI_IO_PM1_STS_PWRBTN;
+
+  IoWrite16 (ABase + R_ACPI_IO_PM1_STS, Pm1Sts);
+
+  //
+  // Clear the GPE and PM enable
+  //
+  IoWrite16 (ABase + R_ACPI_IO_PM1_EN, 0);
+  IoWrite32 (ABase + R_ACPI_IO_GPE0_EN_127_96, 0);
+}
+
+
+/**
+  Function to check if Dirty Warm Reset occurs
+  (Global Reset has been converted to Host Reset)
+
+  @reval TRUE DWR occurs
+  @reval FALSE Normal boot flow
+**/
+BOOLEAN
+PmcIsDwrBootMode (
+  VOID
+  )
+{
+  UINT32      PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+  ASSERT (PchPwrmBase != 0);
+
+  return !!(MmioRead32 (PchPwrmBase + R_PMC_PWRM_HPR_CAUSE0) & B_PMC_PWRM_HPR_CAUSE0_GBL_TO_HOST);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf
new file mode 100644
index 0000000000..2bd57b79f0
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibVer2.inf
@@ -0,0 +1,39 @@
+## @file
+# PEI/DXE/SMM PCH PMC Private Lib Ver2.
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPmcPrivateLibVer2
+FILE_GUID = EB69B12B-6D4C-4B12-BB31-66CBCC4C1DC7
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PmcPrivateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PmcLib
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Pcd]
+gSiPkgTokenSpaceGuid.PcdAcpiBaseAddress
+
+[FixedPcd]
+
+[Sources]
+PmcPrivateLib.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
new file mode 100644
index 0000000000..72a21cfe14
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PeiDxeSmmPmcPrivateLibWithS3.inf
@@ -0,0 +1,40 @@
+## @file
+# PEI/DXE/SMM PCH private PMC Lib.
+# This part of PMC lib includes S3BootScript support
+#
+# All function in this library is available for PEI, DXE, and SMM,
+# But do not support UEFI RUNTIME environment call.
+#
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiDxeSmmPmcPrivateLibWithS3
+FILE_GUID = 5890CA5A-1955-4A02-A09C-01E4150606CC
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = PmcPrivateLibWithS3
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PciSegmentLib
+PmcLib
+PcdLib
+S3BootScriptLib
+PchPciBdfLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+TigerlakeSiliconPkg/SiPkg.dec
+
+
+[Sources]
+PmcPrivateLibWithS3.c
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
new file mode 100644
index 0000000000..4f04765886
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLib.c
@@ -0,0 +1,166 @@
+/** @file
+  PCH private PMC Library for all PCH generations.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, 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/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PchPcrLib.h>
+#include <Library/PchInfoLib.h>
+#include <Library/PmcPrivateLib.h>
+
+/**
+  This function checks if GbE device is supported (not disabled by fuse)
+
+  @retval GbE support state
+**/
+BOOLEAN
+PmcIsGbeSupported (
+  VOID
+  )
+{
+  //
+  // Get fuse info from PWRMBASE + FUSE_SS_DIS_RD_2
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_FUSE_DIS_RD_2) & B_PMC_PWRM_FUSE_DIS_RD_2_GBE_FUSE_SS_DIS) == 0);
+}
+
+/**
+  This function checks if LAN wake from DeepSx is enabled
+
+  @retval Lan Wake state
+**/
+BOOLEAN
+PmcIsLanDeepSxWakeEnabled (
+  VOID
+  )
+{
+  //
+  // Get wake info from PWRMBASE + DSX_CFG
+  //
+  return ((MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_DSX_CFG) & (UINT32) B_PMC_PWRM_DSX_CFG_LAN_WAKE_EN) != 0);
+}
+
+/**
+  This function checks if eSPI SMI Lock is set
+
+  @retval eSPI SMI Lock state
+**/
+BOOLEAN
+PmcIsEspiSmiLockSet (
+  VOID
+  )
+{
+  return ((MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A)) & B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK) != 0);
+}
+
+/**
+  This function sets SW SMI Rate.
+
+  @param[in] SwSmiRate        Refer to PMC_SWSMI_RATE for possible values
+**/
+VOID
+PmcSetSwSmiRate (
+  IN PMC_SWSMI_RATE          SwSmiRate
+  )
+{
+  UINT32        PchPwrmBase;
+  STATIC UINT8  SwSmiRateRegVal[4] = {
+    V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_1_5MS,
+    V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_16MS,
+    V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_32MS,
+    V_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL_64MS
+  };
+
+  ASSERT (SwSmiRate <= PmcSwSmiRate64ms);
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  //
+  // SWSMI_RATE_SEL BIT (PWRMBASE offset 1020h[7:6]) bits are in RTC well
+  //
+  MmioAndThenOr8 (
+    PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A,
+    (UINT8)~B_PMC_PWRM_GEN_PMCON_A_SWSMI_RTSL,
+    SwSmiRateRegVal[SwSmiRate]
+    );
+}
+
+/**
+  This function sets Periodic SMI Rate.
+
+  @param[in] PeriodicSmiRate        Refer to PMC_PERIODIC_SMI_RATE for possible values
+**/
+VOID
+PmcSetPeriodicSmiRate (
+  IN PMC_PERIODIC_SMI_RATE    PeriodicSmiRate
+  )
+{
+  UINT32        PchPwrmBase;
+  STATIC UINT8  PeriodicSmiRateRegVal[4] = {
+    V_PMC_PWRM_GEN_PMCON_A_PER_SMI_8S,
+    V_PMC_PWRM_GEN_PMCON_A_PER_SMI_16S,
+    V_PMC_PWRM_GEN_PMCON_A_PER_SMI_32S,
+    V_PMC_PWRM_GEN_PMCON_A_PER_SMI_64S
+  };
+
+  ASSERT (PeriodicSmiRate <= PmcPeriodicSmiRate64s);
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioAndThenOr8 (
+    PchPwrmBase + R_PMC_PWRM_GEN_PMCON_A,
+    (UINT8)~B_PMC_PWRM_GEN_PMCON_A_PER_SMI_SEL,
+    PeriodicSmiRateRegVal[PeriodicSmiRate]
+    );
+}
+
+/**
+  This function reads Power Button Level
+
+  @retval State of PWRBTN# signal (0: Low, 1: High)
+**/
+UINT8
+PmcGetPwrBtnLevel (
+  VOID
+  )
+{
+  if (MmioRead32 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_B) & B_PMC_PWRM_GEN_PMCON_B_PWRBTN_LVL) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+/**
+  This function gets Group to GPE0 configuration
+
+  @param[out] GpeDw0Value       GPIO Group to GPE_DW0 assignment
+  @param[out] GpeDw1Value       GPIO Group to GPE_DW1 assignment
+  @param[out] GpeDw2Value       GPIO Group to GPE_DW2 assignment
+**/
+VOID
+PmcGetGpioGpe (
+  OUT UINT32    *GpeDw0Value,
+  OUT UINT32    *GpeDw1Value,
+  OUT UINT32    *GpeDw2Value
+  )
+{
+  UINT32 Data32;
+
+  Data32 = MmioRead32 ((UINTN) (PmcGetPwrmBase () + R_PMC_PWRM_GPIO_CFG));
+
+  *GpeDw0Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW0) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW0);
+  *GpeDw1Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW1) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW1);
+  *GpeDw2Value = ((Data32 & B_PMC_PWRM_GPIO_CFG_GPE0_DW2) >> N_PMC_PWRM_GPIO_CFG_GPE0_DW2);
+}
diff --git a/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
new file mode 100644
index 0000000000..02acd0d688
--- /dev/null
+++ b/Silicon/Intel/TigerlakeSiliconPkg/IpBlock/Pmc/LibraryPrivate/PeiDxeSmmPmcPrivateLib/PmcPrivateLibWithS3.c
@@ -0,0 +1,122 @@
+/** @file
+  PCH private PMC Library.
+  All function in this library is available for PEI, DXE, and SMM,
+  But do not support UEFI RUNTIME environment call.
+
+  Copyright (c) 2021, 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/BaseLib.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Library/S3BootScriptLib.h>
+#include <Library/PmcLib.h>
+#include <Library/PmcPrivateLib.h>
+
+/**
+  This S3 BootScript only function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+**/
+VOID
+PmcDisableCf9GlobalResetInS3BootScript (
+  VOID
+  )
+{
+  UINT32                          Data;
+
+  UINT32                          PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  Data = MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3);
+
+  Data &= (UINT32) ~B_PMC_PWRM_ETR3_CF9GR;
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PchPwrmBase +
+    R_PMC_PWRM_ETR3,
+    1,
+    &Data
+    );
+}
+
+/**
+  This S3 BootScript only function disables triggering Global Reset of both
+  the Host and the ME partitions after CF9h write of 6h or Eh.
+  Global Reset configuration is locked after programming
+**/
+VOID
+PmcDisableCf9GlobalResetWithLockInS3BootScript (
+  VOID
+  )
+{
+  UINT32                          Data;
+
+  UINT32                          PchPwrmBase;
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  Data = MmioRead32 (PchPwrmBase + R_PMC_PWRM_ETR3);
+
+  Data &= (UINT32) ~B_PMC_PWRM_ETR3_CF9GR;
+  Data |= (UINT32) B_PMC_PWRM_ETR3_CF9LOCK;
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint32,
+    (UINTN) PchPwrmBase +
+    R_PMC_PWRM_ETR3,
+    1,
+    &Data
+    );
+}
+
+/**
+  This function sets SMI Lock with S3 Boot Script programming
+**/
+VOID
+PmcLockSmiWithS3BootScript (
+  VOID
+  )
+{
+  UINT32  PchPwrmBase;
+
+  PchPwrmBase = PmcGetPwrmBase ();
+
+  MmioOr8 ((UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B), B_PMC_PWRM_GEN_PMCON_B_SMI_LOCK);
+
+  S3BootScriptSaveMemWrite (
+    S3BootScriptWidthUint8,
+    (UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B),
+    1,
+    (VOID *) (UINTN) (PchPwrmBase + R_PMC_PWRM_GEN_PMCON_B)
+    );
+}
+
+/**
+  This function sets eSPI SMI Lock
+  @attention This function must be called after eSPI SMI generation has been enabled.
+    This setting is required in all boot modes and before EndOfDxe.
+    If set value will be restored upon S3 resume by bootscript.
+**/
+VOID
+PmcLockEspiSmiWithS3BootScript (
+  VOID
+  )
+{
+  UINT8   Data8Or;
+  UINT8   Data8And;
+
+  Data8Or  = (UINT8) (B_PMC_PWRM_GEN_PMCON_A_ESPI_SMI_LOCK >> 8);
+  Data8And = (UINT8)~((B_PMC_PWRM_GEN_PMCON_A_PWR_FLR | B_PMC_PWRM_GEN_PMCON_A_HOST_RST_STS) >> 8);
+
+  MmioAndThenOr8 (PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1, Data8And, Data8Or);
+  S3BootScriptSaveMemReadWrite (
+    S3BootScriptWidthUint8,
+    PmcGetPwrmBase () + R_PMC_PWRM_GEN_PMCON_A + 1,
+    &Data8Or,
+    &Data8And
+    );
+}
-- 
2.24.0.windows.2



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#71208): https://edk2.groups.io/g/devel/message/71208
Mute This Topic: https://groups.io/mt/80375665/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-






More information about the edk2-devel-archive mailing list