alder_lake_bios/Intel/AlderLake/AlderLakePlatSamplePkg/Setup/IccSetup.c

810 lines
24 KiB
C

/** @file
;******************************************************************************
;* Copyright (c) 2012 - 2020, Insyde Software Corp. 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.
;*
;******************************************************************************
*/
/**@file
@copyright
INTEL CONFIDENTIAL
Copyright 2009 - 2021 Intel Corporation.
The source code contained or described herein and all documents related to the
source code ("Material") are owned by Intel Corporation or its suppliers or
licensors. Title to the Material remains with Intel Corporation or its suppliers
and licensors. The Material may contain trade secrets and proprietary and
confidential information of Intel Corporation and its suppliers and licensors,
and is protected by worldwide copyright and trade secret laws and treaty
provisions. No part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in any way
without Intel's prior express written permission.
No license under any patent, copyright, trade secret or other intellectual
property right is granted to or conferred upon you by disclosure or delivery
of the Materials, either expressly, by implication, inducement, estoppel or
otherwise. Any license under such intellectual property rights must be
express and approved by Intel in writing.
Unless otherwise agreed by Intel in writing, you may not remove or alter
this notice or any other notice embedded in Materials by Intel or
Intel's suppliers or licensors in any way.
This file contains a 'Sample Driver' and is licensed as such under the terms
of your license agreement with Intel or your vendor. This file may be modified
by the user, subject to the additional terms of the license agreement.
@par Specification Reference:
**/
#include <Base.h>
#include <Protocol/HiiConfigAccess.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeMeLib.h>
#include <Library/HiiLib.h>
#include <PlatformNvRamHookLib.h>
//[-start-200215-IB06462109-remove]//
//#include <SetupPrivate.h>
//[-end-200215-IB06462109-remove]//
#include <SetupVariable.h>
#include <IccSetupData.h>
#include "PlatformBoardId.h"
//[-start-200215-IB06462109-remove]//
//#include "OemSetup.h"
//[-end-200215-IB06462109-remove]//
#include <Library/ConfigBlockLib.h>
#include <WdtAppVariable.h>
//[-start-200215-IB06462109-add]//
#include "IccSetup.h"
#include <SetupUtility.h>
#include <ChipsetCmos.h>
#include <Library/PchInfoLib.h>
#include <Library/CmosLib.h>
//[-end-200215-IB06462109-add]//
#define HZ_TO_10KHZ 10000
#pragma pack(1)
typedef struct {
UINT8 NumProfiles;
UINT8 Profile;
UINT8 ProfileSelectionAllowed;
UINT8 RegLock;
} ICC_PROFILE_DATA;
#pragma pack()
static ICC_CLOCK_SETTINGS mSettingsBclk;
static ICC_CLOCK_SETTINGS mDefaultsBclk;
static BOOLEAN mProfileChanged = FALSE;
static BOOLEAN mClockChanged = 0;
static ICC_PROFILE_DATA mIccProfileData = {0};
GLOBAL_REMOVE_IF_UNREFERENCED EFI_HII_HANDLE gHiiHandle;
GLOBAL_REMOVE_IF_UNREFERENCED BOOLEAN gIccReset = FALSE;
//[-start-191111-IB10189001-add]//
SA_SETUP mSaSetup;
//[-end-191111-IB10189001-add]//
/**
Update ICC setup variable from clock data.
@param[in] ClockSettings Pointer to the ICC_CLOCK_SETTINGS buffer.
@param[out] IccSetupPtr Pointer to the ICC_SETUP_DATA buffer.
**/
VOID
UpdateClockData (
IN ICC_CLOCK_SETTINGS ClockSettings,
OUT ICC_SETUP_DATA *IccSetupPtr
)
{
IccSetupPtr->Frequency = (UINT16) ((ClockSettings.Freq + (HZ_TO_10KHZ / 2)) / HZ_TO_10KHZ);
IccSetupPtr->Spread = ClockSettings.SscPercent;
}
/**
Extract clock data from ICC setup variable.
@param[in] IccSetupPtr Pointer to the ICC_SETUP_DATA buffer.
@param[out] ClockSettings Pointer to the ICC_CLOCK_SETTINGS buffer.
**/
VOID
ExtractClockData (
IN ICC_SETUP_DATA *IccSetupPtr,
OUT ICC_CLOCK_SETTINGS *ClockSettings
)
{
ClockSettings->UserFreq = HZ_TO_10KHZ * IccSetupPtr->Frequency;
ClockSettings->SscPercent = IccSetupPtr->Spread;
ClockSettings->SscMode = ICC_SSC_DOWN;
ClockSettings->ReqClock = CLOCK1;
}
/**
Reads string from Hii database. Allocates memory.
Caller of this function is responsible for freeing it.
@param[in] StringId Hii String ID.
@param[out] BufferPtr Pointer to string buffer.
**/
VOID
GetStringFromHii (
IN EFI_STRING_ID StringId,
OUT UINT16 **BufferPtr
)
{
CHAR16* StrBuffer = 0;
UINTN StrLen = 0;
HiiLibGetString (gHiiHandle, StringId, StrBuffer, &StrLen);
StrBuffer = AllocatePool (StrLen);
ASSERT (StrBuffer != NULL);
if (StrBuffer != NULL) {
HiiLibGetString (gHiiHandle, StringId, StrBuffer, &StrLen);
}
*BufferPtr = StrBuffer;
}
/**
Checks if provided settings are equal to clock's defaults
@param[in] RequestedSetting Requested ICC clock setting.
@retval TRUE Requested ICC setting is same as default
@retval FALSE Requested ICC setting is not same as default
**/
BOOLEAN
AreSettingsAsDefault (
IN ICC_CLOCK_SETTINGS *RequestedSetting
)
{
if (RequestedSetting->Freq == mDefaultsBclk.Freq &&
RequestedSetting->SscMode == mDefaultsBclk.SscMode &&
RequestedSetting->SscPercent == mDefaultsBclk.SscPercent ) {
return TRUE;
} else {
return FALSE;
}
}
/**
This function displays the clock range checked value.
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Action Specifies the type of action taken by the browser.
@param[in] KeyValue A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param[in] Type The type of value for the question.
@param[in] Value A pointer to the data being sent to the original exporting driver.
@param[out] ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_UNSUPPORTED The function is not supported.
**/
EFI_STATUS
IccCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
//
// Cannot access ICC menu after EOP.
//
if (MeIsAfterEndOfPost ()) {
return EFI_UNSUPPORTED;
}
switch (KeyValue) {
case KEY_ICC_FREQ2:
if (Action >= EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
mClockChanged = TRUE;
Value->u16 = (UINT16)(mDefaultsBclk.Freq / HZ_TO_10KHZ);
return EFI_SUCCESS;
} else if (Action == EFI_BROWSER_ACTION_CHANGING) {
mClockChanged = TRUE;
if (Value->u16 < (UINT16)(mSettingsBclk.MinFreq / HZ_TO_10KHZ)) {
Value->u16 = (UINT16)(mSettingsBclk.MinFreq / HZ_TO_10KHZ);
} else if (Value->u16 > (UINT16)(mSettingsBclk.MaxFreq / HZ_TO_10KHZ)) {
Value->u16 = (UINT16)(mSettingsBclk.MaxFreq / HZ_TO_10KHZ);
}
return EFI_SUCCESS;
} else {
return EFI_UNSUPPORTED;
}
case KEY_ICC_SPREAD2:
if (Action >= EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
mClockChanged = TRUE;
Value->u8 = mDefaultsBclk.SscPercent;
return EFI_SUCCESS;
} else if (Action == EFI_BROWSER_ACTION_CHANGING) {
mClockChanged = TRUE;
if (Value->u8 > mSettingsBclk.MaxSscPercent) {
Value->u8 = (UINT8) mSettingsBclk.MaxSscPercent;
}
return EFI_SUCCESS;
} else {
return EFI_UNSUPPORTED;
}
default:
return EFI_UNSUPPORTED;
}
}
/**
Update Hii string based on clock setting.
**/
VOID
UpdateSubmenuStrings (
VOID
)
{
EFI_STATUS Status;
UINTN VariableSize;
SETUP_DATA SetupData;
UINT32 SetupAttributes;
VariableSize = sizeof (SETUP_DATA);
Status = gRT->GetVariable (
L"Setup",
&gSetupVariableGuid,
&SetupAttributes,
&VariableSize,
&SetupData
);
ASSERT_EFI_ERROR (Status);
if (SetupData.DccClkCtrl == 1) {
//
// Init Discrete Bclk Config String
//
InitString (
gHiiHandle,
STRING_TOKEN (STR_BCLK_SOURCE_VALUE),
L"Discrete Clock"
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_DCC_CPU_BCLK_FREQ_VALUE),
L"%d MHz",
SetupData.CurrentCpuBclkFreq
);
InitString (
gHiiHandle,
STRING_TOKEN (STR_DCC_PEGDMI_CLK_FREQ_VALUE),
L"%d MHz",
SetupData.CurrentPegDmiClkFreq
);
}
}
/**
Setup callback executed when user selects a ICC Profile from the BIOS UI.
Changes visibility of other options
@param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
@param[in] Action Specifies the type of action taken by the browser.
@param[in] QuestionId A unique value which is sent to the original exporting driver
so that it can identify the type of data to expect.
@param[in] Type The type of value for the question.
@param[in] Value A pointer to the data being sent to the original exporting driver.
@param[out] ActionRequest On return, points to the action requested by the callback function.
@retval EFI_SUCCESS The callback successfully handled the action.
@retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
@retval EFI_DEVICE_ERROR The variable could not be saved.
@retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
@retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
**/
EFI_STATUS
EFIAPI
IccProfileCallback (
IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
IN EFI_BROWSER_ACTION Action,
IN EFI_QUESTION_ID KeyValue,
IN UINT8 Type,
IN EFI_IFR_TYPE_VALUE *Value,
OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
)
{
UINTN Size = sizeof (ICC_SETUP_DATA);
ICC_SETUP_DATA IccSetup;
EFI_STRING RequestString = NULL;
DEBUG ((DEBUG_INFO, "(ICC) %a() enter\n", __FUNCTION__));
if (Action != EFI_BROWSER_ACTION_CHANGING && Action < EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
return EFI_UNSUPPORTED;
}
if (MeIsAfterEndOfPost ()) {
return EFI_UNSUPPORTED;
}
if (Action >= EFI_BROWSER_ACTION_DEFAULT_STANDARD) {
if (mIccProfileData.ProfileSelectionAllowed) {
//
// Perform change only if profile is selectable by BIOS
//
Value->u8 = 0;
}
}
//
// sanity check: can't choose profile that doesn't exist
//
if (Value->u8 > mIccProfileData.NumProfiles - 1) {
Value->u8 = mIccProfileData.NumProfiles - 1;
}
//
// when profile is changed, most other icc options can't be changed before reboot. hide those options.
//
RequestString = HiiConstructRequestString (RequestString, OFFSET_OF (ICC_SETUP_DATA, AllowAdvancedOptions), sizeof (IccSetup.AllowAdvancedOptions));
if (mProfileChanged || (Value->u8 != mIccProfileData.Profile)) {
HiiGetBrowserData (&gIccGuid, ICC_SETUP_DATA_C_NAME, Size, (UINT8 *)&IccSetup);
IccSetup.AllowAdvancedOptions = DONT_DISPLAY;
HiiSetBrowserData (&gIccGuid, ICC_SETUP_DATA_C_NAME, sizeof (ICC_SETUP_DATA), (UINT8 *)&IccSetup, RequestString);
} else if (!mProfileChanged && (Value->u8 == mIccProfileData.Profile)) {
HiiGetBrowserData (&gIccGuid, ICC_SETUP_DATA_C_NAME, Size, (UINT8 *)&IccSetup);
IccSetup.AllowAdvancedOptions = DISPLAY;
HiiSetBrowserData (&gIccGuid, ICC_SETUP_DATA_C_NAME, sizeof (ICC_SETUP_DATA), (UINT8 *)&IccSetup, RequestString);
}
FreePool (RequestString);
return EFI_SUCCESS;
}
/**
Allows protocol's clients to request that WDT be turned on and periodically kicked
during BIOS execution during next boot. Sets a nonvolatile variable that will be
read by WdtAppPei during next boot.
@retval EFI_SUCCESS Set variable successfully
@retval other Other status returned from variable services
**/
EFI_STATUS
RequestWdtAfterReboot (
VOID
)
{
EFI_STATUS Status;
WDT_PERSISTENT_DATA WdtPersistentData;
WdtPersistentData.Enable = 1;
Status = gRT->SetVariable (
WDT_PERSISTENT_DATA_C_NAME,
&gWdtPersistentDataGuid,
EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
sizeof (WDT_PERSISTENT_DATA),
&WdtPersistentData
);
return Status;
}
/**
Executed by setup calback function
Based on data entered by user, sends clock change requests to ICC OverClocking
Writing to susram or flash requires that old susram and flash contents be invalidated
In case of any problem, messagebox is displayed so user can know what corrective action is required
@param[in] RequestedClockSettings Initial clock divider value
**/
VOID
ApplyClockSettings (
IN ICC_CLOCK_SETTINGS *RequestedClockSettings
)
{
EFI_STATUS Status;
UINTN VariableSize;
UINT32 VariableAttributes;
Status = HeciSetIccClockSettings (RequestedClockSettings);
DEBUG ((DEBUG_INFO, "(ICC) HeciSetIccClockSettings, Status = %r\n", Status));
VariableSize = sizeof (SA_SETUP);
Status = gRT->GetVariable (
L"SaSetup",
&gSaSetupVariableGuid,
&VariableAttributes,
&VariableSize,
&mSaSetup
);
ASSERT_EFI_ERROR (Status);
if (!EFI_ERROR (Status)) {
//
// Update the BclkFrequency setup option to sync with MRC and XTU
//
mSaSetup.BclkFrequency = RequestedClockSettings->UserFreq / HZ_TO_10KHZ;
Status = gRT->SetVariable (
L"SaSetup",
&gSaSetupVariableGuid,
VariableAttributes,
VariableSize,
&mSaSetup
);
ASSERT_EFI_ERROR (Status);
DEBUG ((DEBUG_INFO, "(ICC) BclkFrequency = %d\n", mSaSetup.BclkFrequency));
DEBUG ((DEBUG_INFO, "(ICC) BclkOverride = %d\n", mSaSetup.BclkOverride));
if (!AreSettingsAsDefault (RequestedClockSettings)) {
RequestWdtAfterReboot ();
}
}
}
/**
Print ICC setup configuration
@param[in] IccSetup The ICC_SETUP_DATA buffer.
**/
VOID
DebugDumpConfig (
IN ICC_SETUP_DATA IccSetup
)
{
DEBUG ((DEBUG_INFO, "Frequency : %d\n", IccSetup.Frequency));
DEBUG ((DEBUG_INFO, "Spread : %d\n", IccSetup.Spread));
DEBUG ((DEBUG_INFO, "ShowFrequency : %d\n", IccSetup.ShowFrequency));
DEBUG ((DEBUG_INFO, "ShowSpread : %d\n", IccSetup.ShowSpread));
DEBUG ((DEBUG_INFO, "ShowProfile : %d\n", IccSetup.ShowProfile));
DEBUG ((DEBUG_INFO, "Profile : %d\n", IccSetup.Profile));
DEBUG ((DEBUG_INFO, "AllowAdvancedOptions: %d\n", IccSetup.AllowAdvancedOptions));
}
/**
Initialize ICC Hii Handle
@param[in] HiiHandle Hii Handle.
@param[in] Class Setup form class.
**/
VOID
InitIccStrings (
IN EFI_HII_HANDLE HiiHandle,
IN UINT16 Class
)
{
if (Class != ADVANCED_FORM_SET_CLASS) {
return;
}
gHiiHandle = HiiHandle;
}
/**
Get ICC clock setting from CSME
**/
VOID
GetClockSettings (
VOID
)
{
EFI_STATUS Status;
static BOOLEAN StringInit = FALSE;
DEBUG ((DEBUG_INFO, "%a() enter\n", __FUNCTION__));
if (StringInit) {
return;
}
//
// Get BCLK Settings
//
ZeroMem (&mSettingsBclk, sizeof (ICC_CLOCK_SETTINGS));
mSettingsBclk.ReqClock = CLOCK1;
Status = HeciGetIccClockSettings (&mSettingsBclk);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_INFO, "(ICC) Get Clock Settings message failed, clock 1. Status = %r\n", Status));
return;
}
DEBUG ((DEBUG_INFO, "Bclk: \n"));
DEBUG ((DEBUG_INFO, " ReqClock = %d\n", mSettingsBclk.ReqClock));
DEBUG ((DEBUG_INFO, " SettingType = %d\n", mSettingsBclk.SettingType));
DEBUG ((DEBUG_INFO, " Flags = %d\n", mSettingsBclk.Flags));
DEBUG ((DEBUG_INFO, " Freq = %d\n", mSettingsBclk.Freq));
DEBUG ((DEBUG_INFO, " UserFreq = %d\n", mSettingsBclk.UserFreq));
DEBUG ((DEBUG_INFO, " MaxFreq = %d\n", mSettingsBclk.MaxFreq));
DEBUG ((DEBUG_INFO, " MinFreq = %d\n", mSettingsBclk.MinFreq));
DEBUG ((DEBUG_INFO, " SscMode = %d\n", mSettingsBclk.SscMode));
DEBUG ((DEBUG_INFO, " SscPercent = %d\n", mSettingsBclk.SscPercent));
DEBUG ((DEBUG_INFO, " MaxSscPercent = %d\n", mSettingsBclk.MaxSscPercent));
StringInit = TRUE;
}
/**
Update setup visibility based on ICC setup information.
@param[in] SetupPtr Pointer to the ICC_SETUP_DATA buffer.
**/
VOID
UpdateVisibility (
IN ICC_SETUP_DATA *SetupPtr
)
{
UINT32 MeMode;
EFI_STATUS Status;
BOOLEAN IsSetupHidden;
HECI_PROTOCOL *Heci;
IsSetupHidden = FALSE;
Status = gBS->LocateProtocol (
&gHeciProtocolGuid,
NULL,
(VOID **) &Heci
);
if (!EFI_ERROR (Status)) {
Status = Heci->GetMeMode (&MeMode);
if (EFI_ERROR (Status) || (MeMode != ME_MODE_NORMAL)) {
IsSetupHidden = TRUE;
} else if (MeIsAfterEndOfPost ()) {
IsSetupHidden = TRUE;
}
}
if (IsSetupHidden) {
SetupPtr->AllowAdvancedOptions = DONT_DISPLAY;
} else {
SetupPtr->AllowAdvancedOptions = DISPLAY;
}
if (IsSetupHidden || mIccProfileData.ProfileSelectionAllowed == DONT_DISPLAY) {
SetupPtr->ShowProfile = DONT_DISPLAY;
} else {
SetupPtr->ShowProfile = DISPLAY;
}
if (IsSetupHidden || mSettingsBclk.MaxFreq == mSettingsBclk.MinFreq) {
SetupPtr->ShowFrequency = DONT_DISPLAY;
} else {
SetupPtr->ShowFrequency = DISPLAY;
}
if (IsSetupHidden || mSettingsBclk.SscMode == ICC_SSC_NONE) {
SetupPtr->ShowSpread = DONT_DISPLAY;
} else {
SetupPtr->ShowSpread = DISPLAY;
}
}
/**
Update ICC setup configuration.
**/
VOID
IccExtractConfig (
VOID
)
{
ICC_SETUP_DATA IccSetup;
EFI_STATUS Status;
UINTN Size;
UINT8 IccProfile;
UINT8 NumIccProfiles;
UINT8 IccSelectAllowed;
ICC_PROFILE_DESC *ProfileDescriptions;
UINT32 VariableAttr;
HECI_PROTOCOL *Heci;
DEBUG ((DEBUG_INFO, "(ICC) %a() enter\n", __FUNCTION__));
Size = sizeof (IccSetup);
Status = gRT->GetVariable (ICC_SETUP_DATA_C_NAME, &gIccGuid, &VariableAttr, &Size, &IccSetup);
if (EFI_ERROR (Status)) {
VariableAttr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
ZeroMem ((VOID *) &IccSetup, sizeof (ICC_SETUP_DATA));
}
Status = gBS->LocateProtocol (&gHeciProtocolGuid, NULL, (VOID **) &Heci);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "Locate Heci Protocol Status = %r\n", Status));
IccSetup.AllowAdvancedOptions = DONT_DISPLAY;
IccSetup.ShowProfile = DONT_DISPLAY;
gRT->SetVariable (
ICC_SETUP_DATA_C_NAME,
&gIccGuid,
VariableAttr,
sizeof (IccSetup),
&IccSetup
);
return;
}
GetClockSettings ();
//
// Get IccProfile and update IccSetup
//
DEBUG ((DEBUG_INFO, "(ICC) Get IccProfile Start...\n"));
ProfileDescriptions = (ICC_PROFILE_DESC *) AllocateZeroPool (sizeof (ICC_PROFILE_DESC) * MAX_NUM_ICC_PROFILES);
if (ProfileDescriptions == NULL) {
DEBUG ((DEBUG_ERROR, "(ICC) Failed to Allocate Memory Resource\n"));
return;
}
Status = HeciGetIccProfile (&IccProfile, &NumIccProfiles, &IccSelectAllowed, ProfileDescriptions);
if (!EFI_ERROR (Status)) {
mIccProfileData.Profile = IccProfile;
if (IccSelectAllowed) {
mIccProfileData.ProfileSelectionAllowed = DISPLAY;
} else {
mIccProfileData.ProfileSelectionAllowed = DONT_DISPLAY;
}
if (NumIccProfiles <= 1) {
// Firmware is unconfgured, and there are no profiles to select
mIccProfileData.ProfileSelectionAllowed = DONT_DISPLAY;
}
mIccProfileData.NumProfiles = NumIccProfiles;
mIccProfileData.RegLock = 0;
IccSetup.Profile = IccProfile;
}
UpdateClockData (mSettingsBclk, &IccSetup);
UpdateVisibility (&IccSetup);
gRT->SetVariable (
ICC_SETUP_DATA_C_NAME,
&gIccGuid,
VariableAttr,
sizeof (IccSetup),
&IccSetup
);
DebugDumpConfig (IccSetup);
}
/**
Determine if ICC profile should be updated.
@param[in] Profile ICC profile.
**/
VOID
MaybeChangeProfile (
IN UINT8 Profile
)
{
static UINT8 LastSavedProfile;
if (!mProfileChanged) {
LastSavedProfile = mIccProfileData.Profile;
}
if (Profile != LastSavedProfile) {
DEBUG ((DEBUG_INFO, "(ICC) Changing profile: old %d, new %d\n", LastSavedProfile, Profile));
HeciSetIccProfile (Profile);
LastSavedProfile = Profile;
mProfileChanged = TRUE;
gIccReset = TRUE;
}
}
/**
Update ICC setup configuration after data changed.
**/
VOID
IccRouteConfig (
VOID
)
{
EFI_STATUS Status;
ICC_SETUP_DATA IccSetup;
UINTN VariableSize;
ICC_CLOCK_SETTINGS ClockSettings;
UINT32 VariableAttributes;
HECI_PROTOCOL *Heci;
DEBUG ((DEBUG_INFO, "(ICC) %a() enter\n", __FUNCTION__));
ZeroMem ((VOID *) &IccSetup, sizeof (ICC_SETUP_DATA));
Status = gBS->LocateProtocol (&gHeciProtocolGuid, NULL, (VOID **) &Heci);
if (EFI_ERROR (Status) || MeIsAfterEndOfPost ()) {
return;
}
VariableSize = sizeof (SA_SETUP);
Status = gRT->GetVariable (
L"SaSetup",
&gSaSetupVariableGuid,
&VariableAttributes,
&VariableSize,
&mSaSetup
);
ASSERT_EFI_ERROR (Status);
VariableSize = sizeof (ICC_SETUP_DATA);
gRT->GetVariable (ICC_SETUP_DATA_C_NAME, &gIccGuid, &VariableAttributes, &VariableSize, &IccSetup);
MaybeChangeProfile (IccSetup.Profile);
ZeroMem (&ClockSettings, sizeof (ICC_CLOCK_SETTINGS));
if (!mProfileChanged && IccSetup.AllowAdvancedOptions) {
//
// Update BCLK settings if needed
//
if (IccSetup.AllowAdvancedOptions && mClockChanged) {
gIccReset = TRUE;
mClockChanged = FALSE;
ExtractClockData (&IccSetup, &ClockSettings);
///
/// Set permanent and applied on warm reset flags based on BclkChangeType
///
if (mSaSetup.BclkChangeWarmReset) {
ClockSettings.CurrentFlags.Flags.Type = 0;
ClockSettings.CurrentFlags.Flags.ForcePowerFlow = 1;
gIccReset = TRUE;
} else {
switch (mSaSetup.BclkChangeContinues) {
case ICC_BCLK_PERM_NO_WR:
ClockSettings.CurrentFlags.Flags.Type = 0;
ClockSettings.CurrentFlags.Flags.ForcePowerFlow = 0;
gIccReset = FALSE;
break;
case ICC_BCLK_REAL_TIME:
ClockSettings.CurrentFlags.Flags.Type = 1;
ClockSettings.CurrentFlags.Flags.ForcePowerFlow = 0;
gIccReset = FALSE;
break;
default:
break;
}
}
ApplyClockSettings (&ClockSettings);
}
}
}
//[-start-191111-IB10189001-add]//
VOID
DefaultIccSetup (
VOID
)
{
EFI_STATUS Status;
ICC_SETUP_DATA IccSetup = {0};
UINTN Size = sizeof(ICC_SETUP_DATA);
Status = gRT->GetVariable (ICC_SETUP_DATA_C_NAME, &gIccGuid, NULL, &Size, &IccSetup);
ASSERT_EFI_ERROR (Status);
Status = gRT->SetVariable (
ICC_SETUP_DATA_C_NAME_CURRENT,
&gIccGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS,
Size,
&IccSetup
);
ASSERT_EFI_ERROR (Status);
return;
}
//[-end-191111-IB10189001-add]//