/** @file This file is SampleCode for Intel SA PEI Policy initialization. Copyright (c) 2019 - 2020 Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include "PeiSaPolicyInit.h" #include /** PcieCardResetWorkAround performs PCIe Card reset on root port @param[in out] SiPreMemPolicyPpi SI_PREMEM_POLICY_PPI @retval EFI_SUCCESS The policy is installed and initialized. **/ EFI_STATUS PcieCardResetWorkAround ( IN OUT SI_PREMEM_POLICY_PPI *SiPreMemPolicyPpi ) { EFI_STATUS Status; SA_MISC_PEI_PREMEM_CONFIG *MiscPeiPreMemConfig; SWITCHABLE_GRAPHICS_CONFIG *SgGpioData; Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSaMiscPeiPreMemConfigGuid, (VOID *)&MiscPeiPreMemConfig); ASSERT_EFI_ERROR(Status); Status = GetConfigBlock((VOID *)SiPreMemPolicyPpi, &gSwitchableGraphicsConfigGuid, (VOID *)&SgGpioData); ASSERT_EFI_ERROR(Status); if (SgGpioData->SaRtd3Pcie0Gpio.GpioSupport != NotSupported) { /// /// dGPU is present. /// If PCIe Mode or SG Muxless /// Power on MXM /// Configure GPIOs to drive MXM in PCIe mode or SG Muxless /// else /// Do Nothing /// if ((MiscPeiPreMemConfig->SgMode == SgModeMuxless) || (MiscPeiPreMemConfig->SgMode == SgModeDgpu)) { DEBUG((DEBUG_INFO, "Configure GPIOs for driving the dGPU.\n")); /// /// Drive DGPU HOLD RST Enable to make sure we hold reset /// PcieGpioWrite ( SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo, SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active, GP_ENABLE ); /// /// wait 100ms /// MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND); /// /// Drive DGPU PWR EN to Power On MXM /// PcieGpioWrite ( SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.GpioNo, SgGpioData->SaRtd3Pcie0Gpio.PwrEnable.Active, GP_ENABLE ); /// /// wait 300ms /// MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterPwrEn) * STALL_ONE_MILLI_SECOND); /// /// Drive DGPU HOLD RST Disabled to remove reset /// PcieGpioWrite ( SgGpioData->SaRtd3Pcie0Gpio.HoldRst.GpioNo, SgGpioData->SaRtd3Pcie0Gpio.HoldRst.Active, GP_DISABLE ); /// /// wait 100ms /// MicroSecondDelay((MiscPeiPreMemConfig->SgDelayAfterHoldReset) * STALL_ONE_MILLI_SECOND); } } return EFI_SUCCESS; } /** PCIe GPIO Write @param[in] Gpio - GPIO Number @param[in] Active - GPIO Active Information; High/Low @param[in] Level - Write GPIO value (0/1) **/ VOID PcieGpioWrite ( IN UINT32 Gpio, IN BOOLEAN Active, IN BOOLEAN Level ) { EFI_STATUS Status; if (Active == 0) { Level = (~Level) & 0x1; } Status = GpioSetOutputValue(Gpio, (UINT32)Level); if (Status != EFI_SUCCESS) { return; } }