From: Vu Nguyen <[email protected]>
Provide Mt. Jade specific segment number for each Root Complex and
function to handle the PCIe PERST.
Cc: Thang Nguyen <[email protected]>
Cc: Chuong Tran <[email protected]>
Cc: Phong Vo <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Michael D Kinney <[email protected]>
Cc: Ard Biesheuvel <[email protected]>
Cc: Nate DeSimone <[email protected]>
Signed-off-by: Nhi Pham <[email protected]>
---
Platform/Ampere/JadePkg/Jade.dsc | 2 +-
Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf | 27 +++++
Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.c | 115
++++++++++++++++++++
3 files changed, 143 insertions(+), 1 deletion(-)
diff --git a/Platform/Ampere/JadePkg/Jade.dsc b/Platform/Ampere/JadePkg/Jade.dsc
index 23a297d0dbeb..9315c1c71cc7 100644
--- a/Platform/Ampere/JadePkg/Jade.dsc
+++ b/Platform/Ampere/JadePkg/Jade.dsc
@@ -85,7 +85,7 @@ [LibraryClasses]
#
# Pcie Board
#
-
BoardPcieLib|Silicon/Ampere/AmpereAltraPkg/Library/BoardPcieLibNull/BoardPcieLibNull.inf
+ BoardPcieLib|Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf
################################################################################
#
diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf
b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf
new file mode 100644
index 000000000000..1d722bceff2c
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.inf
@@ -0,0 +1,27 @@
+## @file
+#
+# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001B
+ BASE_NAME = BoardPcieLib
+ FILE_GUID = 062191A6-E113-4FD6-84C7-E400B4B34759
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = BoardPcieLib
+
+[Sources]
+ BoardPcieLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec
+
+[LibraryClasses]
+ DebugLib
+ GpioLib
+ TimerLib
diff --git a/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.c
b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.c
new file mode 100644
index 000000000000..4a9da7eeb4fe
--- /dev/null
+++ b/Platform/Ampere/JadePkg/Library/BoardPcieLib/BoardPcieLib.c
@@ -0,0 +1,115 @@
+/** @file
+ Pcie board specific driver to handle asserting PERST signal to Endpoint
+ card. PERST asserting is via group of GPIO pins to CPLD as Platform
Specification.
+
+ Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Guid/RootComplexInfoHob.h>
+#include <Library/DebugLib.h>
+#include <Library/GpioLib.h>
+#include <Library/TimerLib.h>
+#include <Platform/Ac01.h>
+
+#define RCA_MAX_PERST_GROUPVAL 62
+#define RCB_MAX_PERST_GROUPVAL 46
+
+VOID
+BoardPcieReleaseAllPerst (
+ IN UINT8 SocketId
+ )
+{
+ UINT32 GpioIndex, GpioPin;
+
+ // Write 1 to all GPIO[16..21] to release all PERST
+ GpioPin = AC01_GPIO_PINS_PER_SOCKET * SocketId + 16;
+ for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
+ GpioModeConfig (GpioPin + GpioIndex, GpioConfigOutHigh);
+ }
+}
+
+/**
+ Assert PERST of PCIe controller
+
+ @param[in] RootComplex Root Complex instance.
+ @param[in] PcieIndex PCIe controller index of input Root
Complex.
+ @param[in] IsPullToHigh Target status for the PERST.
+
+ @retval RETURN_SUCCESS The operation is successful.
+ @retval Others An error occurred.
+**/
+RETURN_STATUS
+EFIAPI
+BoardPcieAssertPerst (
+ IN AC01_ROOT_COMPLEX *RootComplex,
+ IN UINT8 PcieIndex,
+ IN BOOLEAN IsPullToHigh
+ )
+{
+ UINT32 GpioGroupVal, Val, GpioIndex, GpioPin;
+
+ if (!IsPullToHigh) {
+ if (RootComplex->Type == RootComplexTypeA) {
+ //
+ // RootComplexTypeA: RootComplex->ID: 0->3 ; PcieIndex: 0->3
+ //
+ GpioGroupVal = RCA_MAX_PERST_GROUPVAL - RootComplex->ID *
MaxPcieControllerA - PcieIndex;
+ } else {
+ //
+ // RootComplexTypeB: RootComplex->ID: 4->7 ; PcieIndex: 0->7
+ //
+ GpioGroupVal = RCB_MAX_PERST_GROUPVAL - (RootComplex->ID -
MaxRootComplexA) * MaxPcieControllerB - PcieIndex;
+ }
+
+ // Update the value of GPIO[16..21]. Corresponding PERST line will be
decoded by CPLD.
+ GpioPin = AC01_GPIO_PINS_PER_SOCKET * RootComplex->Socket + 16;
+ for (GpioIndex = 0; GpioIndex < 6; GpioIndex++) {
+ Val = (GpioGroupVal & 0x3F) & (1 << GpioIndex);
+ if (Val == 0) {
+ GpioModeConfig (GpioPin + GpioIndex, GpioConfigOutLow);
+ } else {
+ GpioModeConfig (GpioPin + GpioIndex, GpioConfigOutHigh);
+ }
+ }
+
+ // Keep reset as low as 100 ms as specification
+ MicroSecondDelay (100 * 1000);
+ } else {
+ BoardPcieReleaseAllPerst (RootComplex->Socket);
+ }
+
+ return RETURN_SUCCESS;
+}
+
+/**
+ Override the segment number for a root complex with a board specific number.
+
+ @param[in] RootComplex Root Complex instance with properties.
+
+ @retval Segment number corresponding to the input root complex.
+ Default segment number is 0x0F.
+**/
+UINT16
+BoardPcieGetSegmentNumber (
+ IN AC01_ROOT_COMPLEX *RootComplex
+ )
+{
+ UINT8 Ac01BoardSegment[PLATFORM_CPU_MAX_SOCKET][AC01_PCIE_MAX_ROOT_COMPLEX] =
+ {
+ { 0x0C, 0x0D, 0x01, 0x00, 0x02, 0x03, 0x04, 0x05 },
+ { 0x10, 0x11, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B }
+ };
+
+ if (RootComplex->Socket < PLATFORM_CPU_MAX_SOCKET
+ && RootComplex->ID < AC01_PCIE_MAX_ROOT_COMPLEX) {
+ return Ac01BoardSegment[RootComplex->Socket][RootComplex->ID];
+ }
+
+ // Return default segment number
+ return 0x0F;