hc
2024-03-22 a0752693d998599af469473b8dc239ef973a012f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/** @file
  This file is SampleCode for Intel SA PEI Policy initialization.
 
 
  Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent
**/
 
#include "PeiSaPolicyInit.h"
#include <Library/ConfigBlockLib.h>
 
/**
  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;
  }
}