alder_lake_bios/Intel/AlderLake/AlderLakeChipsetPkg/Library/PeiOemSvcChipsetLib/OemSvcMxmDgpuPowerSequence.c

346 lines
11 KiB
C

/** @file
This function offers an interface for OEM code to change the MXM GPU power enable sequence.
;******************************************************************************
;* Copyright (c) 2018 - 2021, Insyde Software Corporation. All Rights Reserved.
;*
;* You may not reproduce, distribute, publish, display, perform, modify, adapt,
;* transmit, broadcast, present, recite, release, license or otherwise exploit
;* any part of this publication in any form, by any means, without the prior
;* written permission of Insyde Software Corporation.
;*
;******************************************************************************
*/
#include <Library/PeiOemSvcChipsetLib.h>
#if 0
//
// If you need modify HG information HOB data or use HG PPI to change power enable sequence,
// please remember add HobLib and PeiServicesLib into project own INF file.
//
#include <Guid/H2OHgInfoHob.h>
#include <Library/BaseMemoryLib.h>
#include <Library/GpioCfgLib.h>
#include <Library/Hoblib.h>
#include <Library/PeiServicesLib.h>
#include <Ppi/HybridGraphics.h>
#include <HybridGraphicsDefine.h>
typedef
EFI_STATUS
(EFIAPI *HYBRID_GRAPHICS_CUSTOMIZATION) (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
);
//
// Function Prototypes
//
STATIC
EFI_STATUS
GetHgInfoHobAndLocateHgPpi (
IN OUT H2O_HYBRID_GRAPHICS_PPI **HgPpi,
IN OUT HG_INFORMATION_DATA_HOB **HgData
);
EFI_STATUS
BaseOnSkuIdChangeHgMode (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
);
EFI_STATUS
BaseOnHgModePowerEnableGpuThroughEc (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
);
EFI_STATUS
BaseOnSkuIdPowerEnableGpuThroughEc (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
);
EFI_STATUS
ModifiedGpioPowerEnableSequence (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
);
#endif
/**
This function offers an interface for OEM code to change the MXM GPU power enable sequence
and modify the Hybrid Graphics Information data HOB.
@param[in] None
@retval EFI_UNSUPPORTED - Returns unsupported by default.
@retval EFI_MEDIA_CHANGED - Alter the Configuration Parameter.
@retval EFI_SUCCESS - The function performs the same operation as caller.
The caller will skip the specified behavior and assuming
that it has been handled completely by this function.
**/
EFI_STATUS
OemSvcMxmDgpuPowerSequence (
VOID
)
{
#if 0
EFI_STATUS Status;
H2O_HYBRID_GRAPHICS_PPI *HgPpi;
HG_INFORMATION_DATA_HOB *HgData;
HYBRID_GRAPHICS_CUSTOMIZATION CustomizationFunction;
Status = GetHgInfoHobAndLocateHgPpi (&HgPpi, &HgData);
if (EFI_ERROR (Status)) {
return EFI_UNSUPPORTED;
}
//
// There are 4 samples below, OEM can base different case to change customization function.
//
CustomizationFunction = ModifiedGpioPowerEnableSequence;
return (CustomizationFunction) (HgPpi, HgData);
#else
return EFI_UNSUPPORTED;
#endif
}
#if 0
/**
Prepare HG infromation data HOB and HG PPI services this module needed.
@param[in, out] HgData - A double pointer of HG information data HOB,
for OEM runtime modify HG related data.
@param[in, out] HgPpi - A double pointer of PEI Hybrid Graphics PPI Function
for HG GPIO read/write and stall functions.
@retval EFI_SUCCESS - Get HG information data HOB and PEI HG PPI successfully.
@retval !EFI_SUCCESS - Get HG information data HOB or PPI service failed.
**/
STATIC
EFI_STATUS
GetHgInfoHobAndLocateHgPpi (
IN OUT H2O_HYBRID_GRAPHICS_PPI **HgPpi,
IN OUT HG_INFORMATION_DATA_HOB **HgData
)
{
EFI_PEI_HOB_POINTERS Hob;
EFI_STATUS Status;
(*HgData) = NULL;
//
// Locate PEI Hybrid Graphics PPI
//
Status = PeiServicesLocatePpi (
&gH2OHybridGraphicsPpiGuid,
0,
NULL,
HgPpi
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Get Hybrid Graphics Information Data HOB
//
Status = PeiServicesGetHobList (&Hob.Raw);
while (!END_OF_HOB_LIST (Hob)) {
if (Hob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION && CompareGuid (&Hob.Guid->Name, &gH2OHgInformationDataHobGuid)) {
(*HgData) = (HG_INFORMATION_DATA_HOB *) (Hob.Header);
break;
}
Hob.Raw = GET_NEXT_HOB (Hob);
}
if ((*HgData) == NULL) {
return EFI_NOT_FOUND;
}
return EFI_SUCCESS;
}
/**
Sample 1:
If OEM need base on different SKU ID to change the HG mode,
but still need HG PEIM power enable sequence, please refer this function.
@param[in] HgData - A pointer of HG information data HOB,
for OEM runtime modify HG related data.
@param[in] HgPpi - A pointer of PEI Hybrid Graphics PPI Function
for HG GPIO read/write and stall functions.
@retval EFI_MEDIA_CHANGED - It means the OEM service change the HG information data HOB,
but still need MXM GPU power enable sequence in HG PEI module.
**/
EFI_STATUS
BaseOnSkuIdChangeHgMode (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
)
{
/*
UINT8 SkuId;
SkuId = GetSkuId ();
if (SkuId == InternalOnlySkuId) {
HgData->HgMode = HgModeDisabled;
} else if (SkuId == DiscreteOnlySkuId) {
HgData->HgMode = HgModeDgpu;
} else if (SkuId == DualGraphicsSkuId) {
HgData->HgMode = HgModeMuxless;
} else {
HgData->HgMode = HgModeDisabled;
}
*/
return EFI_MEDIA_CHANGED;
}
/**
Sample 2:
If OEM need base on HG mode to do different power enable sequence through EC, please refer this function.
@param[in] HgData - A pointer of HG information data HOB,
for OEM runtime modify HG related data.
@param[in] HgPpi - A pointer of PEI Hybrid Graphics PPI Function
for HG GPIO read/write and stall functions.
@retval EFI_SUCCESS - It means MXM GPU power enable sequence already done and success,
doesn't need do anythings else in HG PEI module.
**/
EFI_STATUS
BaseOnHgModePowerEnableGpuThroughEc (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
)
{
/*
if (HgData->HgMode == HgModeDisabled) {
//
// Internal only sku need power down the discrete MXM GPU.
//
ECRamWrite (EcOffsetPowerControl, EcOffsetDgpuPowerDisable);
} else {
//
// Discrete only sku or HG sku need power enable the discrete MXM GPU.
//
ECRamWrite (EcOffsetPowerControl, EcOffsetDgpuPowerEnable);
}
*/
return EFI_SUCCESS;
}
/**
Sample 3:
If OEM need base on different SKU ID to change the HG mode,
then base on HG mode to do different power enable sequence through EC, please refer this function.
@param[in] HgData - A pointer of HG information data HOB,
for OEM runtime modify HG related data.
@param[in] HgPpi - A pointer of PEI Hybrid Graphics PPI Function
for HG GPIO read/write and stall functions.
@retval EFI_SUCCESS - It means MXM GPU power enable sequence already done and success,
doesn't need do anythings else in HG PEI module.
**/
EFI_STATUS
BaseOnSkuIdPowerEnableGpuThroughEc (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
)
{
/*
UINT8 SkuId;
SkuId = GetSkuId ();
if (SkuId == InternalOnlySkuId) {
HgData->HgMode = HgModeDisabled;
} else if (SkuId == DiscreteOnlySkuId) {
HgData->HgMode = HgModeDgpu;
} else if (SkuId == DualGraphicsSkuId) {
HgData->HgMode = HgModeMuxless;
} else {
HgData->HgMode = HgModeDisabled;
}
if (HgData->HgMode == HgModeDisabled) {
//
// Internal only sku need power down the discrete MXM GPU.
//
ECRamWrite (EcOffsetPowerControl, EcOffsetDgpuPowerDisable);
} else {
//
// Discrete only sku or HG sku need power enable the discrete MXM GPU.
//
ECRamWrite (EcOffsetPowerControl, EcOffsetDgpuPowerEnable);
}
*/
return EFI_SUCCESS;
}
/**
Sample 4:
If OEM need modify the power enable sequence through GPIO pins, please refer this function.
This sampel doesn't have dGPU_PRSNT, EDID_SELECT, dGPU_SELECT and dGPU_PWM_SELECT pins.
@param[in] HgData - A pointer of HG information data HOB,
for OEM runtime modify HG related data.
@param[in] HgPpi - A pointer of PEI Hybrid Graphics PPI Function
for HG GPIO read/write and stall functions.
@retval EFI_SUCCESS - It means MXM GPU power enable sequence already done and success,
doesn't need do anythings else in HG PEI module.
**/
EFI_STATUS
ModifiedGpioPowerEnableSequence (
IN H2O_HYBRID_GRAPHICS_PPI *HgPpi,
IN HG_INFORMATION_DATA_HOB *HgData
)
{
if (HgData->HgMode == HgModeDisabled) {
//
// Internal only sku need power down the discrete MXM GPU.
//
if (HgPpi->GpioRead (HgData->DgpuPwrEnableGpioNo, HgData->DgpuPwrEnableActive) == Active) {
HgPpi->GpioWrite (HgData->DgpuHoldRstGpioNo, HgData->DgpuHoldRstActive, Active);
HgPpi->GpioWrite (HgData->DgpuPwrEnableGpioNo, HgData->DgpuPwrEnableActive, Inactive);
} else {
HgPpi->GpioWrite (HgData->DgpuHoldRstGpioNo, HgData->DgpuHoldRstActive, Inactive);
}
} else {
// Power enable the discrete GPU when dual VGA mode (HG) or discrete GPU only mode.
// Power enable sequence: (1) Active DgpuHoldRst => Delay 100ms
// (2) Active DgpuPwrEnable => Delay 300ms
// (3) Active DgpuVron => Delay 50ms (Different Sequence Here)
// (4) Inactive DgpuHoldRst => Delay 100ms
// If DgpuVron is GPIO_CNL_H_GPP_F10 and high active, please refer this sample.
//
HgPpi->GpioWrite (HgData->DgpuHoldRstGpioNo, HgData->DgpuHoldRstActive, Active);
HgPpi->Stall (HgData->DelayAfterHoldReset * 1000);
HgPpi->GpioWrite (HgData->DgpuPwrEnableGpioNo, HgData->DgpuPwrEnableActive, Active);
HgPpi->Stall (HgData->DelayAfterPwrEn * 1000);
HgPpi->GpioWrite (GPIO_CNL_H_GPP_F10, HighActive, Active); // GPIO46 high active dGPU_VRON pin active
HgPpi->Stall (50 * 1000); // delay 50ms
HgPpi->GpioWrite (HgData->DgpuHoldRstGpioNo, HgData->DgpuHoldRstActive, Inactive);
HgPpi->Stall (HgData->DelayAfterHoldReset * 1000);
}
return EFI_SUCCESS;
}
#endif