/** @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 #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 #include #include #include #include #include #include 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