From: Michael Kubacki <michael.a.kubacki@intel.com>
To: edk2-devel@lists.01.org
Cc: Hao Wu <hao.a.wu@intel.com>, Liming Gao <liming.gao@intel.com>,
Jiewen Yao <jiewen.yao@intel.com>,
Michael D Kinney <michael.d.kinney@intel.com>
Subject: [edk2-platforms/devel-MinPlatform][PATCH v4 3/7] ClevoOpenBoardPkg: Add library instances
Date: Wed, 30 Jan 2019 22:11:13 -0800 [thread overview]
Message-ID: <20190131061117.36916-4-michael.a.kubacki@intel.com> (raw)
In-Reply-To: <20190131061117.36916-1-michael.a.kubacki@intel.com>
Based on KabylakeOpenBoardPkg from the following branch:
https://github.com/tianocore/edk2-platforms/tree/devel-MinPlatform
Library instances shared across Clevo board instances.
* BaseGpioExpanderLib - Support for the TCA6424 IO expander.
* PeiI2cAccessLib - Provides I2C read and write services.
* PeiDTbtInitLib - PEI discrete Thunderbolt initialization services.
* PeiTbtPolicyLib - PEI Thunderbolt policy initialization.
* DxeTbtPolicyLib - DXE Thunderbolt policy initialization.
* TbtCommonLib - Common Thunderbolt services.
Cc: Hao Wu <hao.a.wu@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kubacki <michael.a.kubacki@intel.com>
---
.../Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf | 73 +++
.../Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf | 68 +++
.../Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf | 62 +++
.../Private/PeiDTbtInitLib/PeiDTbtInitLib.inf | 47 ++
.../BaseGpioExpanderLib/BaseGpioExpanderLib.inf | 39 ++
.../Library/PeiI2cAccessLib/PeiI2cAccessLib.inf | 42 ++
.../Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c | 166 ++++++
.../Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c | 321 ++++++++++++
.../Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c | 210 ++++++++
.../Private/PeiDTbtInitLib/PeiDTbtInitLib.c | 572 +++++++++++++++++++++
.../BaseGpioExpanderLib/BaseGpioExpanderLib.c | 315 ++++++++++++
.../Library/PeiI2cAccessLib/PeiI2cAccessLib.c | 121 +++++
12 files changed, 2036 insertions(+)
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
create mode 100644 Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
new file mode 100644
index 0000000000..75a7473060
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.inf
@@ -0,0 +1,73 @@
+## @file
+# Component description file for Tbt functionality
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeTbtPolicyLib
+FILE_GUID = 28ABF346-4E52-4BD3-b1FF-63BA7563C9D4
+VERSION_STRING = 1.0
+MODULE_TYPE = BASE
+LIBRARY_CLASS = DxeTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+UefiRuntimeServicesTableLib
+UefiBootServicesTableLib
+DebugLib
+PostCodeLib
+HobLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber ## CONSUMES
+
+
+[Sources]
+DxeTbtPolicyLib.c
+
+
+[Guids]
+gEfiEndOfDxeEventGroupGuid
+#gSetupVariableGuid
+gTbtInfoHobGuid
+
+[Protocols]
+gDxeTbtPolicyProtocolGuid
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
new file mode 100644
index 0000000000..60ea0ba6f1
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.inf
@@ -0,0 +1,68 @@
+### @file
+# Component information file for Thunderbolt common library
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = TbtCommonLib
+ FILE_GUID = 5F03614E-CB56-40B1-9989-A09E25BBA294
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = TbtCommonLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 EBC
+#
+
+[LibraryClasses]
+ DebugLib
+ PchPcieRpLib
+ PciSegmentLib
+ TimerLib
+ BaseLib
+ GpioLib
+ GpioExpanderLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtSecurityMode ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio5Filter ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWakeupSupport ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotSMI ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtHotNotify ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtSetClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAspm ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtAcDcSwitch ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3Tbt ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReq ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtWin10Support ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtClkReqDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdRtd3TbtOffDelay ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieExtraBusRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemRsvd ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPciePMemAddrRngMax ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber
+
+[Sources]
+ TbtCommonLib.c
+
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
new file mode 100644
index 0000000000..dc9c4ea9f3
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.inf
@@ -0,0 +1,62 @@
+## @file
+# Component description file for Tbt policy
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiTbtPolicyLib
+FILE_GUID = 4A95FDBB-2535-49eb-9A79-D56D24257106
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = PeiTbtPolicyLib
+
+
+[LibraryClasses]
+BaseMemoryLib
+PeiServicesLib
+PeiServicesTablePointerLib
+MemoryAllocationLib
+DebugLib
+PostCodeLib
+HobLib
+GpioLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+ IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Pcd]
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerEn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtControllerType ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtPcieRpNumber ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtBootOn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtUsbOn ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwr ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtGpio3ForcePwrDly ## CONSUMES
+gBoardModuleTokenSpaceGuid.PcdDTbtCioPlugEventGpioPad ## CONSUMES
+
+[Sources]
+PeiTbtPolicyLib.c
+
+[Guids]
+gTbtInfoHobGuid
+
+[Ppis]
+gEfiPeiReadOnlyVariable2PpiGuid
+gPeiTbtPolicyPpiGuid
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
new file mode 100644
index 0000000000..b99fd3433c
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.inf
@@ -0,0 +1,47 @@
+### @file
+# Component description file for PEI DTBT Init library.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiDTbtInitLib
+ FILE_GUID = 06768A8D-8152-403f-83C1-59584FD2B438
+ VERSION_STRING = 1.0
+ MODULE_TYPE = PEIM
+ LIBRARY_CLASS = PeiDTbtInitLib
+
+[LibraryClasses]
+ PeiServicesLib
+ DebugLib
+ PcdLib
+ TbtCommonLib
+ PciSegmentLib
+ PeiTbtPolicyLib
+ PchPmcLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Ppis]
+ gPeiTbtPolicyPpiGuid ## CONSUMES
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress ## CONSUMES
+
+[Sources]
+ PeiDTbtInitLib.c
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
new file mode 100644
index 0000000000..2750645711
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.inf
@@ -0,0 +1,39 @@
+### @file
+# Library producing Gpio Expander functionality.
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = BaseGpioExpanderLib
+ FILE_GUID = D10AE2A4-782E-427E-92FB-BB74505ED329
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = GpioExpanderLib
+
+[LibraryClasses]
+ BaseLib
+ IoLib
+ DebugLib
+ TimerLib
+ PchSerialIoLib
+ I2cAccessLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ BaseGpioExpanderLib.c
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
new file mode 100644
index 0000000000..9f4c1cbb80
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.inf
@@ -0,0 +1,42 @@
+### @file
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials are licensed and made available under
+# the terms and conditions of the BSD License which accompanies this distribution.
+# The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+###
+
+[Defines]
+ INF_VERSION = 0x00010017
+ BASE_NAME = PeiI2cAccessLib
+ FILE_GUID = 72CD3A7B-FEA5-4F5E-9165-4DD12187BB13
+ VERSION_STRING = 1.0
+ MODULE_TYPE = BASE
+ LIBRARY_CLASS = PeiI2cAccessLib
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ DebugLib
+ TimerLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MinPlatformPkg/MinPlatformPkg.dec
+ ClevoOpenBoardPkg/OpenBoardPkg.dec
+ SecurityPkg/SecurityPkg.dec
+ KabylakeSiliconPkg/SiPkg.dec
+
+[Sources]
+ PeiI2cAccessLib.c
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
new file mode 100644
index 0000000000..1783d8c6b4
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/DxeTbtPolicyLib/DxeTbtPolicyLib.c
@@ -0,0 +1,166 @@
+/** @file
+ This file is DxeTbtPolicyLib library.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <DxeTbtPolicyLibrary.h>
+#include <TbtBoardInfo.h>
+#include <Protocol/DxeTbtPolicy.h>
+#include <Guid/HobList.h>
+#include <Library/HobLib.h>
+
+/**
+Update Tbt Policy Callback
+Need to add PCDs for setup options
+**/
+
+VOID
+EFIAPI
+UpdateTbtPolicyCallback (
+ VOID
+ )
+{
+
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtConfig;
+
+ DxeTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ DEBUG ((DEBUG_INFO, "UpdateTbtPolicyCallback\n"));
+
+ Status = gBS->LocateProtocol (
+ &gDxeTbtPolicyProtocolGuid,
+ NULL,
+ (VOID **) &DxeTbtConfig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+ } else {
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd = PcdGet16 (PcdDTbtPcieMemRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd = PcdGet16 (PcdDTbtPciePMemRsvd);
+ DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+
+ DxeTbtConfig->TbtCommonConfig.TbtAspm = PcdGet8 (PcdDTbtAspm);
+ DxeTbtConfig->TbtCommonConfig.TbtHotNotify = PcdGet8 (PcdDTbtHotNotify);
+ DxeTbtConfig->TbtCommonConfig.TbtHotSMI = PcdGet8 (PcdDTbtHotSMI);
+ DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = PcdGet8 (PcdDTbtSetClkReq);
+ DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = PcdGet8 (PcdDTbtWakeupSupport);
+ DxeTbtConfig->TbtCommonConfig.SecurityMode = PcdGet8 (PcdDTbtSecurityMode);
+
+ DxeTbtConfig->TbtCommonConfig.Gpio5Filter = PcdGet8 (PcdDTbtGpio5Filter);
+ DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = PcdGet8 (PcdDTbtAcDcSwitch);
+
+ DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = PcdGet8 (PcdRtd3Tbt);
+ DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = PcdGet16 (PcdRtd3TbtOffDelay);
+ DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = PcdGet8 (PcdRtd3TbtClkReq);
+ DxeTbtConfig->TbtCommonConfig.Win10Support = PcdGet8 (PcdDTbtWin10Support);
+ }
+
+ return;
+}
+
+/**
+ Print DXE TBT Policy
+**/
+VOID
+TbtPrintDxePolicyConfig (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "TbtPrintDxePolicyConfig Start\n"));
+
+ DxeTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ Status = gBS->LocateProtocol (
+ &gDxeTbtPolicyProtocolGuid,
+ NULL,
+ (VOID **) &DxeTbtConfig
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, " gDxeTbtPolicyProtocolGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Print DTBT Policy
+ //
+ DEBUG ((DEBUG_ERROR, " ========================= DXE TBT POLICY ========================= \n"));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieExtraBusRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPcieMemAddrRngMax));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemRsvd));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax = %x\n", DxeTbtConfig->DTbtResourceConfig.DTbtPciePMemAddrRngMax));
+
+
+ //
+ // Print TBT Common Policy
+ //
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAspm = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAspm));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotNotify = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotNotify));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtHotSMI = %x\n", DxeTbtConfig->TbtCommonConfig.TbtHotSMI));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtLtr = %x\n", DxeTbtConfig->TbtCommonConfig.TbtLtr));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtSetClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.TbtSetClkReq));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport = %x\n", DxeTbtConfig->TbtCommonConfig.TbtWakeupSupport));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.SecurityMode = %x\n", DxeTbtConfig->TbtCommonConfig.SecurityMode));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Gpio5Filter = %x\n", DxeTbtConfig->TbtCommonConfig.Gpio5Filter));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch = %x\n", DxeTbtConfig->TbtCommonConfig.TbtAcDcSwitch));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3Tbt = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3Tbt));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtOffDelay));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReq));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay = %x\n", DxeTbtConfig->TbtCommonConfig.Rtd3TbtClkReqDelay));
+ DEBUG ((DEBUG_INFO, "DxeTbtConfig->TbtCommonConfig.Win10Support = %x\n", DxeTbtConfig->TbtCommonConfig.Win10Support));
+
+ return;
+}
+
+/**
+ Install Tbt Policy
+
+ @param[in] ImageHandle Image handle of this driver.
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallTbtPolicy (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ DXE_TBT_POLICY_PROTOCOL *DxeTbtPolicy;
+
+ DEBUG ((DEBUG_INFO, "Install DXE TBT Policy\n"));
+
+ DxeTbtPolicy = NULL;
+ //Alloc memory for DxeTbtPolicy
+ DxeTbtPolicy = (DXE_TBT_POLICY_PROTOCOL *) AllocateZeroPool (sizeof (DXE_TBT_POLICY_PROTOCOL));
+ if (DxeTbtPolicy == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBS->InstallProtocolInterface (
+ &ImageHandle,
+ &gDxeTbtPolicyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ DxeTbtPolicy
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Install Tbt Secure Boot List protocol failed\n"));
+ }
+ return Status;
+}
+
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
new file mode 100644
index 0000000000..52871cf447
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiDxeSmmTbtCommonLib/TbtCommonLib.c
@@ -0,0 +1,321 @@
+/** @file
+ Common Thunderbolt functions.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/DebugLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Library/PchPcieRpLib.h>
+#include <Library/TbtCommonLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseLib.h>
+#include <Library/GpioLib.h>
+
+
+/**
+ Selects the proper TBT Root port to assign resources
+ based on the user input value
+
+ @param[in] SetupData Pointer to Setup data
+
+ @retval TbtSelectorChosen Rootport number.
+**/
+VOID
+GetRootporttoSetResourcesforTbt (
+ IN UINTN RpIndex,
+ OUT UINT8 *RsvdExtraBusNum,
+ OUT UINT16 *RsvdPcieMegaMem,
+ OUT UINT8 *PcieMemAddrRngMax,
+ OUT UINT16 *RsvdPciePMegaMem,
+ OUT UINT8 *PciePMemAddrRngMax,
+ OUT BOOLEAN *SetResourceforTbt
+ )
+{
+ UINTN TbtRpNumber;
+ TbtRpNumber = (UINTN) PcdGet8 (PcdDTbtPcieRpNumber);
+
+ if (RpIndex == (TbtRpNumber - 1)) {
+ *RsvdExtraBusNum = PcdGet8 (PcdDTbtPcieExtraBusRsvd);
+ *RsvdPcieMegaMem = PcdGet16 (PcdDTbtPcieMemRsvd);
+ *PcieMemAddrRngMax = PcdGet8 (PcdDTbtPcieMemAddrRngMax);
+ *RsvdPciePMegaMem = PcdGet16 (PcdDTbtPciePMemRsvd);
+ *PciePMemAddrRngMax = PcdGet8 (PcdDTbtPciePMemAddrRngMax);
+ *SetResourceforTbt = TRUE;
+ }
+ else {
+ *SetResourceforTbt = FALSE;
+ }
+ }
+
+/**
+ Internal function to Wait for Tbt2PcieDone Bit.to Set or clear
+ @param[in] CommandOffsetAddress Tbt2Pcie Register Address
+ @param[in] TimeOut Time out with 100 ms garnularity
+ @param[in] Tbt2PcieDone Wait condition (wait for Bit to Clear/Set)
+ @param[out] *Tbt2PcieValue Function Register value
+**/
+BOOLEAN
+InternalWaitforCommandCompletion(
+ IN UINT64 CommandOffsetAddress,
+ IN UINT32 TimeOut,
+ IN BOOLEAN Tbt2PcieDone,
+ OUT UINT32 *Tbt2PcieValue
+ )
+{
+ BOOLEAN ReturnFlag;
+ UINT32 Tbt2PcieCheck;
+
+ ReturnFlag = FALSE;
+ while (TimeOut-- > 0) {
+ *Tbt2PcieValue = PciSegmentRead32 (CommandOffsetAddress);
+
+ if (0xFFFFFFFF == *Tbt2PcieValue ) {
+ //
+ // Device is not here return now
+ //
+ ReturnFlag = FALSE;
+ break;
+ }
+
+ if(Tbt2PcieDone) {
+ Tbt2PcieCheck = *Tbt2PcieValue & TBT2PCIE_DON_R;
+ } else {
+ Tbt2PcieCheck = !(*Tbt2PcieValue & TBT2PCIE_DON_R);
+ }
+
+ if (Tbt2PcieCheck) {
+ ReturnFlag = TRUE;
+ break;
+ }
+
+ MicroSecondDelay(TBT_MAIL_BOX_DELAY);
+ }
+ return ReturnFlag;
+}
+/**
+ Get Security Level.
+ @param[in] Bus Bus number Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Command Command for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+UINT8
+GetSecLevel (
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ )
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ UINT8 ReturnFlag;
+
+ ReturnFlag = 0xFF;
+
+ DEBUG ((DEBUG_INFO, "GetSecLevel() \n"));
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ if(InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue)) {
+ ReturnFlag = (UINT8) (0xFF & (RegisterValue >> 8));
+ }
+
+ PciSegmentWrite32 (Pcie2Tbt, 0);
+
+ InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "Security Level configured to %x \n", ReturnFlag));
+
+ return ReturnFlag;
+}
+
+/**
+ Set Security Level.
+ @param[in] Data Security State
+ @param[in] Bus Bus number for Host Router (DTBT)
+ @param[in] Device Device number for Host Router (DTBT)
+ @param[in] Function Function number for Host Router (DTBT)
+ @param[in] Command Command for Host Router (DTBT)
+ @param[in] Timeout Time out with 100 ms garnularity
+**/
+BOOLEAN
+SetSecLevel (
+ IN UINT8 Data,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Command,
+ IN UINT32 Timeout
+ )
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+
+ ReturnFlag = FALSE;
+
+ DEBUG ((DEBUG_INFO, "SetSecLevel() \n"));
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, (Data << 8) | Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "RegisterValue %x \n", RegisterValue));
+ PciSegmentWrite32 (Pcie2Tbt, 0);
+
+ InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, FALSE, &RegisterValue);
+ DEBUG ((DEBUG_INFO, "Return value %x \n", ReturnFlag));
+ return ReturnFlag;
+}
+
+/**
+Based on the Security Mode Selection, BIOS drives FORCE_PWR.
+
+@param[in] GpioNumber
+@param[in] Value
+**/
+VOID
+ForceDtbtPower(
+ IN UINT8 GpioAccessType,
+ IN UINT8 Expander,
+ IN UINT32 GpioNumber,
+ IN BOOLEAN Value
+)
+{
+ if (GpioAccessType == 0x01) {
+ // PCH
+ GpioSetOutputValue (GpioNumber, (UINT32)Value);
+ } else if (GpioAccessType == 0x02) {
+ // IoExpander {TCA6424A}
+ GpioExpSetOutput (Expander, (UINT8)GpioNumber, (UINT8)Value);
+ }
+}
+
+/**
+Execute TBT Mail Box Command
+
+@param[in] Command TBT Command
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+@param[in] Timeout Time out with 100 ms garnularity
+@Retval true if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtCommand(
+ IN UINT8 Command,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 Timeout
+)
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+ PciSegmentWrite32(Pcie2Tbt, 0);
+
+ return ReturnFlag;
+}
+/**
+ Get Pch/Peg Pcie Root Port Device and Function Number for TBT by Root Port physical Number
+
+ @param[in] RpNumber Root port physical number. (0-based)
+ @param[out] RpDev Return corresponding root port device number.
+ @param[out] RpFun Return corresponding root port function number.
+
+ @retval EFI_SUCCESS Root port device and function is retrieved
+ @retval EFI_INVALID_PARAMETER If Invalid Root Port Number or TYPE is Passed
+**/
+EFI_STATUS
+EFIAPI
+GetDTbtRpDevFun (
+ IN BOOLEAN Type,
+ IN UINTN RpNumber,
+ OUT UINTN *RpDev,
+ OUT UINTN *RpFunc
+ )
+{
+ EFI_STATUS Status;
+ UINTN TbtRpDev;
+ UINTN TbtRpFunc;
+
+ Status = EFI_INVALID_PARAMETER; // Update the Status to EFI_SUCCESS if valid input found.
+ //
+ // CNL PCH-H can support up to 24 root ports. PEG0,PEG1 and PEG2 will be
+ // with device number 0x1 and Function number 0,1 and 2 respectively.
+ //
+ if (Type == DTBT_TYPE_PEG)
+ {
+ //
+ // PEG Rootport
+ //
+ if (RpNumber <= 2) {
+ *RpDev = 0x01;
+ *RpFunc = RpNumber;
+ Status = EFI_SUCCESS;
+ }
+ }
+ if (Type == DTBT_TYPE_PCH)
+ {
+ //
+ // PCH Rootport
+ //
+ if (RpNumber <= 23) {
+ Status = GetPchPcieRpDevFun (RpNumber, &TbtRpDev, &TbtRpFunc);
+ *RpDev = TbtRpDev;
+ *RpFunc = TbtRpFunc;
+ }
+ }
+
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+BOOLEAN
+IsTbtHostRouter (
+ IN UINT16 DeviceID
+ )
+{
+ switch (DeviceID) {
+ case AR_HR_2C:
+ case AR_HR_4C:
+ case AR_HR_LP:
+ case AR_HR_C0_2C:
+ case AR_HR_C0_4C:
+ case TR_HR_2C:
+ case TR_HR_4C:
+ return TRUE;
+ }
+
+ return FALSE;
+} // IsTbtHostRouter
+
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
new file mode 100644
index 0000000000..36b49f013e
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/PeiTbtPolicyLib/PeiTbtPolicyLib.c
@@ -0,0 +1,210 @@
+/** @file
+ This file is PeiTbtPolicyLib library.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/PeiServicesLib.h>
+#include <Library/GpioLib.h>
+#include <PiPei.h>
+#include <PeiTbtPolicyLibrary.h>
+#include <Ppi/ReadOnlyVariable2.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Base.h>
+#include <GpioConfig.h>
+
+/**
+ Update PEI TBT Policy Callback
+**/
+VOID
+EFIAPI
+UpdatePeiTbtPolicy (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *VariableServices;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ PeiTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+
+ DEBUG ((DEBUG_INFO, "UpdatePeiTbtPolicy \n"));
+
+ Status = PeiServicesLocatePpi (
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ (VOID **) &VariableServices
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Update DTBT Policy
+ //
+ PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn = PcdGet8 (PcdDTbtControllerEn);
+ if (PcdGet8 (PcdDTbtControllerType) == TYPE_PEG)
+ {
+ PeiTbtConfig-> DTbtControllerConfig.Type = (UINT8) TYPE_PEG;
+ PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = 1; // PEG RP 1 (Function no. 0)
+ }
+ else {
+ PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber = PcdGet8 (PcdDTbtPcieRpNumber);
+ PeiTbtConfig-> DTbtControllerConfig.Type = PcdGet8 (PcdDTbtControllerType);
+ }
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = (GPIO_PAD) PcdGet32 (PcdDTbtCioPlugEventGpioPad);
+ if (GpioCheckFor2Tier(PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad)) {
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 0;
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+ }
+ else {
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = 1;
+ //
+ // Update Signature based on platform GPIO.
+ //
+ PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = SIGNATURE_32('X', 'T', 'B', 'T');
+ }
+ PeiTbtConfig->DTbtCommonConfig.TbtBootOn = PcdGet8 (PcdDTbtBootOn);
+ PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = PcdGet8 (PcdDTbtUsbOn);
+ PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = PcdGet8 (PcdDTbtGpio3ForcePwr);
+ PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = PcdGet16 (PcdDTbtGpio3ForcePwrDly);
+
+ return;
+}
+
+/**
+ Print PEI TBT Policy
+**/
+VOID
+EFIAPI
+TbtPrintPeiPolicyConfig (
+ VOID
+ )
+{
+ DEBUG_CODE_BEGIN ();
+ EFI_STATUS Status;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ PeiTbtConfig = NULL;
+ Status = EFI_NOT_FOUND;
+ DEBUG ((DEBUG_INFO, "TbtPrintPolicyConfig Start\n"));
+
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Print DTBT Policy
+ //
+ DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print BEGIN -----------------\n"));
+ DEBUG ((DEBUG_INFO, "Revision : 0x%x\n", PEI_TBT_POLICY_REVISION));
+ DEBUG ((DEBUG_INFO, "------------------------ PEI_TBT_CONFIG -----------------\n"));
+ DEBUG ((DEBUG_INFO, " Revision : %d\n", PEI_TBT_POLICY_REVISION));
+
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.DTbtControllerEn = %x\n", PeiTbtConfig-> DTbtControllerConfig.DTbtControllerEn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.Type = %x\n", PeiTbtConfig-> DTbtControllerConfig.Type));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRpNumber = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.ForcePwrGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.PcieRstGpio.GpioLevel = %x\n", PeiTbtConfig-> DTbtControllerConfig.PcieRstGpio.GpioLevel));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.GpioPad = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.GpioPad));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignature));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting = %x\n", PeiTbtConfig-> DTbtControllerConfig.CioPlugEventGpio.AcpiGpeSignaturePorting));
+
+
+ //
+ // Print DTBT Common Policy
+ //
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtBootOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtBootOn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.TbtUsbOn = %x\n", PeiTbtConfig->DTbtCommonConfig.TbtUsbOn));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly = %x\n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration = %x\n", PeiTbtConfig->DTbtCommonConfig.DTbtSharedGpioConfiguration));
+ DEBUG ((DEBUG_INFO, "PeiTbtConfig->DTbtCommonConfig.PcieRstSupport = %x\n", PeiTbtConfig->DTbtCommonConfig.PcieRstSupport));
+
+ DEBUG ((DEBUG_INFO, "\n------------------------ TBT Policy (PEI) Print END -----------------\n"));
+ DEBUG_CODE_END ();
+
+ return;
+}
+
+/**
+ Install Tbt Policy
+
+ @retval EFI_SUCCESS The policy is installed.
+ @retval EFI_OUT_OF_RESOURCES Insufficient resources to create buffer
+
+**/
+EFI_STATUS
+EFIAPI
+InstallPeiTbtPolicy (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *PeiTbtPolicyPpiDesc;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ DEBUG ((DEBUG_INFO, "Install PEI TBT Policy\n"));
+
+ PeiTbtConfig = NULL;
+
+ //
+ // Allocate memory for PeiTbtPolicyPpiDesc
+ //
+ PeiTbtPolicyPpiDesc = (EFI_PEI_PPI_DESCRIPTOR *) AllocateZeroPool (sizeof (EFI_PEI_PPI_DESCRIPTOR));
+ ASSERT (PeiTbtPolicyPpiDesc != NULL);
+ if (PeiTbtPolicyPpiDesc == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Allocate memory and initialize all default to zero for PeiTbtPolicy
+ //
+ PeiTbtConfig = (PEI_TBT_POLICY *) AllocateZeroPool (sizeof (PEI_TBT_POLICY));
+ ASSERT (PeiTbtConfig != NULL);
+ if (PeiTbtConfig == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize PPI
+ //
+ PeiTbtPolicyPpiDesc->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ PeiTbtPolicyPpiDesc->Guid = &gPeiTbtPolicyPpiGuid;
+ PeiTbtPolicyPpiDesc->Ppi = PeiTbtConfig;
+
+ Status = PeiServicesInstallPpi (PeiTbtPolicyPpiDesc);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Install PEI TBT Policy failed\n"));
+ }
+ return Status;
+}
+
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
new file mode 100644
index 0000000000..986a1271d8
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Features/Tbt/Library/Private/PeiDTbtInitLib/PeiDTbtInitLib.c
@@ -0,0 +1,572 @@
+/**@file
+ Thunderbolt(TM) Pei Library
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+#include <Library/PeiServicesLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <GpioPinsSklLp.h>
+#include <GpioPinsSklH.h>
+#include <Library/TimerLib.h>
+#include <Library/IoLib.h>
+#include <Library/MmPciLib.h>
+#include <Library/HobLib.h>
+#include <Library/PcdLib.h>
+#include <Library/GpioExpanderLib.h>
+#include <Ppi/ReadOnlyVariable2.h>
+
+#include <Base.h>
+#include <Library/TbtCommonLib.h>
+#include <TbtBoardInfo.h>
+#include <IndustryStandard/Pci22.h>
+#include <Library/PchCycleDecodingLib.h>
+#include <Ppi/PeiTbtPolicy.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiTbtPolicyLib.h>
+#include <Library/PchPmcLib.h>
+#include <Private/Library/PeiDTbtInitLib.h>
+
+/**
+Is host router (For dTBT) or End Point (For iTBT) present before sleep
+
+@param[in] ControllerType - DTBT_CONTROLLER or ITBT_CONTROLLER
+@param[in] Controller - Controller begin offset of CMOS
+
+@Retval TRUE There is a TBT HostRouter presented before sleep
+@Retval FALSE There is no TBT HostRouter presented before sleep
+
+BOOLEAN
+IsHostRouterPresentBeforeSleep(
+IN UINT8 ControllerType,
+IN UINT8 Controller
+)
+{
+ UINT8 SavedState;
+
+ SavedState = (UINT8)GetTbtHostRouterStatus();
+ if (ControllerType == DTBT_CONTROLLER){
+ return ((SavedState & (DTBT_SAVE_STATE_OFFSET << Controller)) == (DTBT_SAVE_STATE_OFFSET << Controller));
+ } else {
+ if (ControllerType == ITBT_CONTROLLER) {
+ return ((SavedState & (ITBT_SAVE_STATE_OFFSET << Controller)) == (ITBT_SAVE_STATE_OFFSET << Controller));
+ }
+ }
+ return 0;
+}
+**/
+
+/**
+Execute TBT PCIE2TBT_SX_EXIT_TBT_CONNECTED Mail Box Command for S4 mode with PreBootAclEnable
+
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+@param[in] Timeout Time out with 100 ms garnularity
+@Retval true if command executes succesfully
+**/
+BOOLEAN
+TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT32 Timeout
+)
+{
+ UINT64 Pcie2Tbt;
+ UINT64 Tbt2Pcie;
+ UINT32 RegisterValue;
+ BOOLEAN ReturnFlag;
+ UINT32 Command;
+
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+ GET_PCIE2TBT_REGISTER_ADDRESS(0, Bus, Device, Function, Pcie2Tbt)
+
+// If PreBootAcl is Enable, we need to enable DATA bit while sending SX EXIT MAIL BOX Command
+ Command = (1 << 8) | PCIE2TBT_SX_EXIT_TBT_CONNECTED;
+ PciSegmentWrite32 (Pcie2Tbt, Command | PCIE2TBT_VLD_B);
+
+ ReturnFlag = InternalWaitforCommandCompletion(Tbt2Pcie, Timeout, TRUE, &RegisterValue);
+
+ PciSegmentWrite32(Pcie2Tbt, 0);
+
+ return ReturnFlag;
+}
+
+/**
+Set the Sleep Mode if the HR is up.
+@param[in] Bus Bus number for Host Router (DTBT)
+@param[in] Device Device number for Host Router (DTBT)
+@param[in] Function Function number for Host Router (DTBT)
+**/
+VOID
+TbtSetSxMode(
+IN UINT8 Bus,
+IN UINT8 Device,
+IN UINT8 Function,
+IN UINT8 TbtBootOn
+)
+{
+ UINT64 TbtUsDevId;
+ UINT64 Tbt2Pcie;
+ UINT32 RegVal;
+ UINT32 MaxLoopCount;
+ UINTN Delay;
+ UINT8 RetCode;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+
+ TbtUsDevId = PCI_SEGMENT_LIB_ADDRESS(0, Bus, Device, Function, 0);
+ GET_TBT2PCIE_REGISTER_ADDRESS(0, Bus, Device, Function, Tbt2Pcie)
+
+ MaxLoopCount = TBT_5S_TIMEOUT; // Wait 5 sec
+ Delay = 100 * 1000;
+ RetCode = 0x62;
+
+ Status = PeiServicesGetBootMode(&BootMode);
+ ASSERT_EFI_ERROR(Status);
+
+ if ((BootMode == BOOT_ON_S4_RESUME) && (TbtBootOn == 2)) {
+ MaxLoopCount = TBT_3S_TIMEOUT;
+ if (!TbtSetPcie2TbtSxExitCommandWithPreBootAclEnable(Bus, Device, Function, MaxLoopCount)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ return;
+ }
+ }
+ else {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_SX_EXIT_TBT_CONNECTED, Bus, Device, Function, MaxLoopCount)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ return;
+ }
+ }
+
+ DEBUG((DEBUG_INFO, "Wait for Dev ID != 0xFF\n"));
+
+ while (MaxLoopCount-- > 0) {
+ //
+ // Check what HR still here
+ //
+ RegVal = PciSegmentRead32(Tbt2Pcie);
+ if (0xFFFFFFFF == RegVal) {
+ RetCode = 0x6F;
+ break;
+ }
+ //
+ // Check completion of TBT link
+ //
+ RegVal = PciSegmentRead32(TbtUsDevId);
+ if (0xFFFFFFFF != RegVal) {
+ RetCode = 0x61;
+ break;
+ }
+
+ MicroSecondDelay(Delay);
+ }
+
+ DEBUG((DEBUG_INFO, "Return code = 0x%x\n", RetCode));
+}
+/**
+ set tPCH25 Timing to 10 ms for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSetTPch25Timing (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ DEBUG ((DEBUG_INFO, "DTbtSetTPch25Timing call Inside\n"));
+ UINT32 PchPwrmBase;
+
+ //
+ //During boot, reboot and wake tPCH25 Timing should be set to 10 ms
+ //
+ PchPwrmBaseGet (&PchPwrmBase);
+ MmioOr32 (
+ (UINTN) (PchPwrmBase + R_PCH_PWRM_CFG),
+ (BIT0 | BIT1)
+ );
+
+ DEBUG((DEBUG_INFO, "DTbtSetTPch25Timing call Return\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Do ForcePower for DTBT Controller
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtForcePower (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+
+ DEBUG ((DEBUG_INFO, "DTbtForcePower call Inside\n"));
+
+ if (PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwr) {
+ DEBUG((DEBUG_INFO, "ForcePwrGpio.GpioPad = %x \n", PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad));
+ ForceDtbtPower(PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioAccessType,PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.Expander, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioPad, PeiTbtConfig-> DTbtControllerConfig.ForcePwrGpio.GpioLevel);
+ DEBUG((DEBUG_INFO, "ForceDtbtPower asserted \n"));
+ MicroSecondDelay(PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly * 1000);
+ DEBUG((DEBUG_INFO, "Delay after ForceDtbtPower = 0x%x ms \n", PeiTbtConfig->DTbtCommonConfig.Gpio3ForcePwrDly));
+ }
+
+ DEBUG ((DEBUG_INFO, "DTbtForcePower call Return\n"));
+ return EFI_SUCCESS;
+}
+
+/**
+ Clear VGA Registers for DTBT.
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtClearVgaRegisters (
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ UINTN RpDev;
+ UINTN RpFunc;
+ EFI_STATUS Status;
+ UINT64 BridngeBaseAddress;
+ UINT16 Data16;
+
+ DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+ // Host router resides should be cleaned
+ //
+
+ BridngeBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0, (UINT32)RpDev, (UINT32)RpFunc, 0);
+ Data16 = PciSegmentRead16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET);
+ Data16 &= (~(EFI_PCI_BRIDGE_CONTROL_VGA | EFI_PCI_BRIDGE_CONTROL_VGA_16));
+ PciSegmentWrite16(BridngeBaseAddress + PCI_BRIDGE_CONTROL_REGISTER_OFFSET, Data16);
+
+ DEBUG ((DEBUG_INFO, "DTbtClearVgaRegisters call Return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "Boot On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtBootOn(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINT32 OrgBusNumberConfiguration;
+ UINTN RpDev;
+ UINTN RpFunc;
+
+ DEBUG((DEBUG_INFO, "DTbtBootOn call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32 (PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+ //
+ //When Thunderbolt(TM) boot [TbtBootOn] is enabled in bios setup we need to do the below:
+ //Bios should send "Boot On" message through PCIE2TBT register
+ //The Boot On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+ //once the Boot On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+ //next step from BIOS is enumeration using SMI
+ //
+
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+ //
+ // Exectue Mail box command "Boot On / Pre-Boot ACL"
+ //
+ //Command may be executed only during boot/reboot and not during Sx exit flow
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 1) {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_BOOT_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Boot On message sent failed \n"));
+ }
+ }
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2) {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_PREBOOTACL, 0xF0, 0, 0, TBT_3S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> DTbtBootOn - Pre-Boot ACL message sent failed \n"));
+ }
+ }
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtBootOn call Return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "USB On".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtUsbOn(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINTN RpDev;
+ UINTN RpFunc;
+ UINT32 OrgBusNumberConfiguration;
+ UINT64 TbtBaseAddress;
+ UINT32 MaxWaitIter;
+ UINT32 RegVal;
+ EFI_BOOT_MODE BootMode;
+
+ DEBUG((DEBUG_INFO, "DTbtUsbOn call Inside\n"));
+
+ Status = EFI_SUCCESS;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+ //
+ //When Thunderbolt(TM) Usb boot [TbtUsbOn] is enabled in bios setup we need to do the below:
+ //Bios should send "Usb On" message through PCIE2TBT register
+ //The Usb On command as described above would include the command and acknowledge from FW (with the default timeout in BIOS),
+ //once the Usb On command is completed it is guaranteed that the AlpineRidge(AR) device is there and the PCI tunneling was done by FW,
+ //next step from BIOS is enumeration using SMI
+ //
+ if (PeiTbtConfig->DTbtCommonConfig.TbtUsbOn) {
+ if (PeiTbtConfig->DTbtCommonConfig.TbtBootOn > 0) {
+ MaxWaitIter = 50; // Wait 5 sec
+ TbtBaseAddress = PCI_SEGMENT_LIB_ADDRESS(0, 0xF0, 0, 0, 0);
+ //
+ // Driver clears the PCIe2TBT Valid bit to support two consicutive mailbox commands
+ //
+ PciSegmentWrite32(TbtBaseAddress + PCIE2TBT_DTBT_R, 0);
+ DEBUG((DEBUG_INFO, "TbtBaseAddress + PCIE2TBT_DTBT_R = 0x%lx \n", TbtBaseAddress + PCIE2TBT_DTBT_R));
+ while (MaxWaitIter-- > 0) {
+ RegVal = PciSegmentRead32(TbtBaseAddress + TBT2PCIE_DTBT_R);
+ if (0xFFFFFFFF == RegVal) {
+ //
+ // Device is not here return now
+ //
+ DEBUG((DEBUG_INFO, "TBT device is not present \n"));
+ break;
+ }
+
+ if (!(RegVal & TBT2PCIE_DON_R)) {
+ break;
+ }
+ MicroSecondDelay(100 * 1000);
+ }
+ }
+
+ Status = PeiServicesGetBootMode(&BootMode);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Exectue Mail box command "Usb On"
+ //
+ //Command may be executed only during boot/reboot and not during S3 exit flow
+ //In case of S4 Exit send USB ON cmd only if Host Router was inactive/not present during S4 entry
+ if ((BootMode == BOOT_ON_S4_RESUME) ) {
+ // USB_ON cmd not required
+ } else {
+ if (!TbtSetPcie2TbtCommand(PCIE2TBT_USB_ON, 0xF0, 0, 0, TBT_5S_TIMEOUT)) {
+ //
+ // Nothing to wait, HR is not responsive
+ //
+ DEBUG((DEBUG_INFO, "<TbtPei> TbtBootSupport - Usb On message sent failed \n"));
+ }
+ }
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtUsbOn call return\n"));
+ return Status;
+}
+
+/**
+ Exectue Mail box command "Sx Exit".
+
+ @param[in] PEI_TBT_POLICY PeiTbtConfig
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval EFI_UNSUPPORTED dTBT is not supported.
+**/
+EFI_STATUS
+EFIAPI
+DTbtSxExitFlow(
+ IN PEI_TBT_POLICY *PeiTbtConfig
+)
+{
+ EFI_STATUS Status;
+ UINT32 OrgBusNumberConfiguration;
+ UINTN RpDev;
+ UINTN RpFunc;
+ UINT32 Count;
+
+ DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Inside\n"));
+
+ Status = EFI_SUCCESS;
+ Count = 0;
+
+ Status = GetDTbtRpDevFun(PeiTbtConfig-> DTbtControllerConfig.Type, PeiTbtConfig-> DTbtControllerConfig.PcieRpNumber - 1, &RpDev, &RpFunc);
+ ASSERT_EFI_ERROR(Status);
+ OrgBusNumberConfiguration = PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET));
+ //
+ // Set Sec/Sub buses to 0xF0
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), 0x00F0F000);
+
+ if ( (PeiTbtConfig->DTbtCommonConfig.TbtBootOn == 2)) {
+ //
+ // WA: When system with TBT 3.1 device, resume SX system need to wait device ready. In document that maximum time out should be 500ms.
+ //
+ while (PciSegmentRead32(PCI_SEGMENT_LIB_ADDRESS(0, 0xf0, 0x0, 0x0, 0x08)) == 0xffffffff) { //End Device will be with Device Number 0x0, Function Number 0x0.
+ MicroSecondDelay(STALL_ONE_MICRO_SECOND * 1000); // 1000usec
+ Count++;
+ if (Count > 10000) { //Allowing Max Delay of 10 sec for CFL-S board.
+ break;
+ }
+ }
+
+ //
+ // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+ // attached devices), BIOS should:
+ // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+ // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+ // 3. Continue regular wake flow.
+ //
+ //
+ // Exectue Mail box command and perform "wait for fast link bring-up" loop
+ //
+ TbtSetSxMode(0xF0, 0, 0, PeiTbtConfig->DTbtCommonConfig.TbtBootOn);
+ }
+ //
+ // Reset Sec/Sub buses to original value
+ //
+ PciSegmentWrite32(PCI_SEGMENT_LIB_ADDRESS (0, 0, RpDev, RpFunc, PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET), OrgBusNumberConfiguration);
+
+ DEBUG((DEBUG_INFO, "DTbtSxExitFlow call Return\n"));
+ return Status;
+}
+
+
+/**
+ Initialize Thunderbolt(TM)
+
+ @retval EFI_SUCCESS The function completes successfully
+ @retval others
+**/
+EFI_STATUS
+EFIAPI
+TbtInit (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ PEI_TBT_POLICY *PeiTbtConfig;
+
+ //
+ // Get the TBT Policy
+ //
+ Status = PeiServicesLocatePpi (
+ &gPeiTbtPolicyPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &PeiTbtConfig
+ );
+ if (EFI_ERROR(Status)) {
+ DEBUG ((DEBUG_ERROR, " gPeiTbtPolicyPpiGuid Not installed!!!\n"));
+ }
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Exectue Mail box command "Boot On"
+ //
+ Status = DTbtBootOn (PeiTbtConfig);
+ //
+ // Exectue Mail box command "Usb On"
+ //
+ Status = DTbtUsbOn (PeiTbtConfig);
+ //
+ //During boot, reboot and wake (bits [1:0]) of PCH PM_CFG register should be
+ //set to 11b - 10 ms (default value is 0b - 10 us)
+ //
+ Status = DTbtSetTPch25Timing (PeiTbtConfig);
+ //
+ // Configure Tbt Force Power
+ //
+ Status = DTbtForcePower (PeiTbtConfig);
+ //
+ // VGA Enable and VGA 16-bit decode registers of Bridge control register of Root port where
+ // Host router resides should be cleaned
+ //
+ Status = DTbtClearVgaRegisters (PeiTbtConfig);
+ //
+ // Upon wake, if BIOS saved pre-Sx Host Router state as active (system went to sleep with
+ // attached devices), BIOS should:
+ // 1. Execute "Sx_Exit_TBT_Connected" mailbox command.
+ // 2. If procedure above returns true, BIOS should perform "wait for fast link bring-up" loop
+ // 3. Continue regular wake flow.
+ //
+ Status = DTbtSxExitFlow (PeiTbtConfig);
+ return EFI_SUCCESS;
+}
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c b/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
new file mode 100644
index 0000000000..34d52527cb
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Library/BaseGpioExpanderLib/BaseGpioExpanderLib.c
@@ -0,0 +1,315 @@
+/** @file
+ Support for IO expander TCA6424.
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/GpioExpanderLib.h>
+#include <Library/I2cAccessLib.h>
+
+//
+// Addresses of registers inside expander
+//
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mInputRegister[3] = {0x0,0x1,0x2};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mOutputRegister[3] = {0x4,0x5,0x6};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mConfigRegister[3] = {0xC,0xD,0xE};
+GLOBAL_REMOVE_IF_UNREFERENCED UINT8 mPolarityRegister[3] = {0x8,0x9,0xA};
+
+#define PCH_SERIAL_IO_I2C4 4
+#define TCA6424_I2C_ADDRESS 0x22
+#define PINS_PER_REGISTER 8
+#define GPIO_EXP_PIN_DIRECTION_OUT 1
+#define GPIO_EXP_PIN_DIRECTION_IN 0
+#define GPIO_EXP_PIN_POLARITY_NORMAL 0
+#define GPIO_EXP_PIN_POLARITY_INVERTED 1
+#define GPIO_EXP_SET_OUTPUT 0
+#define GPIO_EXP_SET_DIR 1
+#define GPIO_EXP_GET_INPUT 2
+#define GPIO_EXP_SET_POLARITY 3
+#define AUTO_INCREMENT 0x80
+
+/**
+ Returns the Controller on which GPIO expander is present.
+
+ This function returns the Controller value
+
+ @param[out] Controller Pointer to a Controller value on
+ which I2C expander is configured.
+
+ @retval EFI_SUCCESS non.
+**/
+EFI_STATUS
+GpioExpGetController (
+ OUT UINT8 *Controller
+ )
+{
+ *Controller = PCH_SERIAL_IO_I2C4;
+ return EFI_SUCCESS;
+}
+
+/**
+ Returns the data from register value giving in the input.
+
+ This function is to get the data from the Expander
+ Registers by following the I2C Protocol communication
+
+
+ @param[in] Bar0 Bar address of the SerialIo Controller
+ @param[in] Address Expander Value with in the Contoller
+ @param[in] Register Address of Input/Output/Configure/Polarity
+ registers with in the Expander
+
+ @retval UINT8 Value returned from the register
+**/
+UINT8
+GpioExpGetRegister (
+ IN UINTN Bar0,
+ IN UINT8 Address,
+ IN UINT8 Register
+ )
+{
+ EFI_STATUS Status;
+ UINT8 WriBuf[1];
+ UINT8 ReBuf[1] = {0};
+
+ WriBuf[0] = Register;
+ Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 1, WriBuf, 1, ReBuf, WAIT_1_SECOND);
+
+ return ReBuf[0];
+}
+/**
+ Set the input register to a give value mentioned in the function.
+
+ This function is to Programm the data value to the Expander
+ Register by following the I2C Protocol communication.
+
+ @param[in] Bar0 Bar address of the SerialIo Controller
+ @param[in] Address Expander Value with in the Contoller
+ @param[in] Register Address of Input/Output/Configure/Polarity
+ registers with in the Expander
+ @param[in] Value Value to set in the mentioned the register
+**/
+VOID
+GpioExpSetRegister (
+ IN UINTN Bar0,
+ IN UINT8 Address,
+ IN UINT8 Register,
+ IN UINT8 Value
+ )
+{
+ EFI_STATUS Status;
+ UINT8 WriBuf[2];
+
+ WriBuf[0] = Register;
+ WriBuf[1] = Value;
+ Status = I2cWriteRead( Bar0, TCA6424_I2C_ADDRESS+Address, 2, WriBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+/**
+ Set the input register to a give value mentioned in the function.
+
+ This function is to update the status of the Gpio Expander
+ pin based on the input Operation value of the caller.This
+ function calculates the exact address of the register with
+ the help of the Register Bank
+
+ @param[in] Controller SerialIo Controller value
+ @param[in] Expander Expander Value with in the Contoller
+ @param[in] Pin Pin with in the Expnader Value
+ @param[in] Value none
+ @param[in] Operation Type of operation (Setoutput/Setdirection
+ /Getinput/Setpolarity)
+ @retval UINT8 Final Value returned from the register
+**/
+UINT8
+GpioExpDecodeRegAccess (
+ IN UINT8 Controller,
+ IN UINT8 Expander,
+ IN UINT8 Pin,
+ IN UINT8 Value,
+ IN UINT8 Operation
+ )
+{
+ UINT8* RegisterBank;
+ UINT8 OldValue;
+ UINT8 NewValue;
+ UINT8 RegisterAddress;
+ UINT8 PinNumber;
+ UINT8 ReturnValue = 0;
+
+ DEBUG ((DEBUG_INFO, "GpioExpDecodeRegAccess() %x:%x:%x:%x:%x\n", Controller, Expander, Pin, Value, Operation));
+ ASSERT(Controller<6);
+ ASSERT(Expander<2);
+ ASSERT(Pin<24);
+ ASSERT(Value<2);
+ ASSERT(Operation<4);
+ //
+ // Find the register Address value based on the OPeration
+ //
+ switch(Operation) {
+ case GPIO_EXP_SET_OUTPUT:
+ RegisterBank = mOutputRegister;
+ break;
+ case GPIO_EXP_SET_DIR:
+ RegisterBank = mConfigRegister;
+ break;
+ case GPIO_EXP_GET_INPUT:
+ RegisterBank = mInputRegister;
+ break;
+ case GPIO_EXP_SET_POLARITY:
+ RegisterBank = mPolarityRegister;
+ break;
+ default:
+ ASSERT(FALSE);
+ return 0;
+ }
+ //
+ // Each bit of register represents each Pin
+ // calaulate the register address and Pinnumber(offset with in register)
+ //
+ if (Pin >= 24) {
+ //
+ // Avoid out-of-bound usage of RegisterBank
+ //
+ return 0;
+ }
+
+ RegisterAddress = RegisterBank[(Pin/PINS_PER_REGISTER)];
+ PinNumber = Pin%PINS_PER_REGISTER;
+
+ OldValue = GpioExpGetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress);
+ //
+ // If it to get the data ,just returned otherwise mark the input value and write the register
+ //
+ if (Operation == GPIO_EXP_GET_INPUT) {
+ ReturnValue = 0x1 & (OldValue>>PinNumber);
+ } else {
+ NewValue = OldValue;
+ NewValue &= ~(BIT0<<PinNumber);
+ NewValue |= (Value<<PinNumber);
+ if(NewValue!=OldValue) {
+ GpioExpSetRegister(FindSerialIoBar(Controller, 0), Expander, RegisterAddress, NewValue);
+ }
+ }
+ return ReturnValue;
+}
+/**
+ Set the Output value for the given Expander Gpio pin.
+
+ This function is to Set the Output value for the GPIO
+ Pin within the giving Expander.
+
+ @param[in] Expander Expander Value with in the Contoller
+ @param[in] Pin Pin with in the Expnader Value
+ @param[in] Value none
+
+**/
+VOID
+GpioExpSetOutput (
+ IN UINT8 Expander,
+ IN UINT8 Pin,
+ IN UINT8 Value
+ )
+{
+ UINT8 Controller;
+ if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+ GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_OUTPUT);
+ }
+}
+/**
+ Set the Direction value for the given Expander Gpio pin.
+
+ This function is to Set the direction value for the GPIO
+ Pin within the giving Expander.
+
+ @param[in] Expander Expander Value with in the Contoller
+ @param[in] Pin Pin with in the Expnader Value
+ @param[in] Value none
+**/
+VOID
+GpioExpSetDirection (
+ IN UINT8 Expander,
+ IN UINT8 Pin,
+ IN UINT8 Value
+ )
+{
+
+ UINT8 Controller;
+ if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+ GpioExpDecodeRegAccess(Controller,Expander,Pin,Value,GPIO_EXP_SET_DIR);
+ }
+}
+
+
+/**
+ Get the input value for the given Expander Gpio pin.
+
+ This function is to get the input value for the GPIO
+ Pin within the giving Expander.
+
+ @param[in] Expander Expander Value with in the Contoller
+ @param[in] Pin Pin with in the Expnader Value
+
+ @retval UINT8 Final Value returned from the register
+**/
+UINT8
+GpioExpGetInput (
+ IN UINT8 Expander,
+ IN UINT8 Pin
+ )
+{
+ UINT8 Controller;
+ if(!EFI_ERROR(GpioExpGetController(&Controller))) {
+ return GpioExpDecodeRegAccess(Controller,Expander,Pin,0,GPIO_EXP_GET_INPUT);
+ }
+ return 0;
+}
+
+/**
+ Configures all registers of a single IO Expander in one go.
+
+ @param[in] Expander Expander number (0/1)
+ @param[in] Direction Bit-encoded direction values. BIT0 is for pin0, etc. 0=output, 1=input
+ @param[in] Polarity Bit-encoded input inversion values. BIT0 is for pin0, etc. 0=normal, 1=inversion
+ @param[in] Output Bit-encoded output state, ignores polarity, only applicable if direction=INPUT. BIT0 is for pin0, etc. 0=low, 1=high
+
+**/
+VOID
+GpioExpBulkConfig (
+ IN UINT8 Expander,
+ IN UINT32 Direction,
+ IN UINT32 Polarity,
+ IN UINT32 Output
+ )
+{
+ UINT8 WriteBuf[4];
+ UINT8 Controller;
+
+ GpioExpGetController(&Controller);
+
+ WriteBuf[0] = mOutputRegister[0] + AUTO_INCREMENT;
+ WriteBuf[1] = Output & 0xFF;
+ WriteBuf[2] = (Output>>8) & 0xFF;
+ WriteBuf[3] = (Output>>16) & 0xFF;
+ I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+ WriteBuf[0] = mPolarityRegister[0] + AUTO_INCREMENT;
+ WriteBuf[1] = Polarity & 0xFF;
+ WriteBuf[2] = (Polarity>>8) & 0xFF;
+ WriteBuf[3] = (Polarity>>16) & 0xFF;
+ I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+ WriteBuf[0] = mConfigRegister[0] + AUTO_INCREMENT;
+ WriteBuf[1] = Direction & 0xFF;
+ WriteBuf[2] = (Direction>>8) & 0xFF;
+ WriteBuf[3] = (Direction>>16) & 0xFF;
+ I2cWriteRead( FindSerialIoBar(Controller,0), TCA6424_I2C_ADDRESS+Expander, 4, WriteBuf, 0, NULL, WAIT_1_SECOND);
+
+}
+
diff --git a/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
new file mode 100644
index 0000000000..64fccfe868
--- /dev/null
+++ b/Platform/Intel/ClevoOpenBoardPkg/Library/PeiI2cAccessLib/PeiI2cAccessLib.c
@@ -0,0 +1,121 @@
+/** @file
+
+Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/I2cAccessLib.h>
+
+EFI_STATUS
+I2cWriteRead (
+ IN UINTN MmioBase,
+ IN UINT8 SlaveAddress,
+ IN UINT8 WriteLength,
+ IN UINT8 *WriteBuffer,
+ IN UINT8 ReadLength,
+ IN UINT8 *ReadBuffer,
+ IN UINT64 TimeBudget
+ //TODO: add Speed parameter
+ )
+{
+ UINT8 ReadsNeeded = ReadLength;
+ UINT64 CutOffTime;
+
+ if ((WriteLength == 0 && ReadLength == 0) ||
+ (WriteLength != 0 && WriteBuffer == NULL) ||
+ (ReadLength != 0 && ReadBuffer == NULL) ) {
+ DEBUG ((DEBUG_ERROR, "I2cWR Invalid Parameters\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Sanity checks to verify the I2C controller is alive
+ // Conveniently, ICON register's values of 0 or FFFFFFFF indicate
+ // I2c controller is out-of-order: either disabled, in D3 or in reset.
+ //
+ if (MmioRead32(MmioBase+R_IC_CON) == 0xFFFFFFFF || MmioRead32(MmioBase+R_IC_CON) == 0x0) {
+ DEBUG ((DEBUG_ERROR, "I2cWR Device Error\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ MmioWrite32(MmioBase+R_IC_ENABLE, 0x0);
+ MmioRead32(MmioBase+0x40);
+ MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+ MmioWrite32(MmioBase+R_IC_SDA_HOLD, 0x001C001C);
+ //
+ // Set I2C Bus Speed at 400 kHz for GPIO Expander
+ //
+ MmioWrite32(MmioBase + R_IC_FS_SCL_HCNT, 128);
+ MmioWrite32(MmioBase + R_IC_FS_SCL_LCNT, 160);
+ MmioWrite32(MmioBase + R_IC_TAR, SlaveAddress);
+ MmioWrite32(MmioBase + R_IC_CON, B_IC_MASTER_MODE | V_IC_SPEED_FAST | B_IC_RESTART_EN | B_IC_SLAVE_DISABLE );
+ MmioWrite32(MmioBase+R_IC_ENABLE, 0x1);
+ CutOffTime = AsmReadTsc() + TimeBudget;
+
+ while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==0 ) {
+ if (AsmReadTsc() > CutOffTime) {
+ DEBUG ((DEBUG_ERROR, "I2cWR timeout\n"));
+ return EFI_TIMEOUT;
+ }
+ }
+
+ while(1) {
+ if(MmioRead32(MmioBase+R_IC_INTR_STAT) & B_IC_INTR_TX_ABRT) {
+ DEBUG ((DEBUG_ERROR, "I2cWR Transfer aborted, reason = 0x%08x\n",MmioRead32(MmioBase+R_IC_TX_ABRT_SOURCE)));
+ MmioRead32(MmioBase+R_IC_CLR_TX_ABRT);
+ MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+ while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+ return EFI_DEVICE_ERROR;
+ }
+ if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_TFNF) {
+ if (WriteLength > 1) {
+ MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+ WriteBuffer++;
+ WriteLength--;
+ } else if (WriteLength==1 && ReadLength != 0) {
+ MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer);
+ WriteBuffer++;
+ WriteLength--;
+ } else if (WriteLength==1 && ReadLength == 0) {
+ MmioWrite32(MmioBase+R_IC_DATA_CMD, *WriteBuffer | B_IC_CMD_STOP);
+ WriteBuffer++;
+ WriteLength--;
+ } else if (ReadLength > 1) {
+ MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ);
+ ReadLength--;
+ } else if (ReadLength == 1) {
+ MmioWrite32(MmioBase+R_IC_DATA_CMD, B_IC_CMD_READ|B_IC_CMD_STOP);
+ ReadLength--;
+ }
+ }
+
+ if (ReadsNeeded) {
+ if (MmioRead32(MmioBase+R_IC_STATUS) & B_IC_STATUS_RFNE) {
+ *ReadBuffer = (UINT8)MmioRead32(MmioBase+R_IC_DATA_CMD);
+ ReadBuffer++;
+ ReadsNeeded--;
+ }
+ }
+ if (WriteLength==0 && ReadsNeeded==0 && !(MmioRead32(MmioBase+R_IC_STATUS)&B_IC_STATUS_ACTIVITY)) {
+ MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+ while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+ DEBUG ((DEBUG_INFO, "I2cWR success\n"));
+ return EFI_SUCCESS;
+ }
+ if (AsmReadTsc() > CutOffTime) {
+ MmioAnd32(MmioBase+R_IC_ENABLE, 0xFFFFFFFE);
+ while ( (MmioRead32(MmioBase+R_IC_ENABLE_STATUS) & 1)==1 ) {}
+ DEBUG ((DEBUG_ERROR, "I2cWR wrong ENST value\n"));
+ return EFI_TIMEOUT;
+ }
+
+ }
+}
+
--
2.16.2.windows.1
next prev parent reply other threads:[~2019-01-31 6:12 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-01-31 6:11 [edk2-platforms/devel-MinPlatform][PATCH v4 0/7] Add initial ClevoOpenBoardPkg Michael Kubacki
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 1/7] ClevoOpenBoardPkg: Add package and headers Michael Kubacki
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 2/7] ClevoOpenBoardPkg/N1xxWU: Add headers Michael Kubacki
2019-01-31 6:11 ` Michael Kubacki [this message]
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 4/7] ClevoOpenBoardPkg/N1xxWU: Add library instances Michael Kubacki
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 5/7] ClevoOpenBoardPkg: Add modules Michael Kubacki
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 6/7] ClevoOpenBoardPkg/N1xxWU: Add DSC and build files Michael Kubacki
2019-01-31 6:11 ` [edk2-platforms/devel-MinPlatform][PATCH v4 7/7] ClevoOpenBoardPkg/N1xxWU: Update DEBUG print level macro usage Michael Kubacki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190131061117.36916-4-michael.a.kubacki@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox