810 lines
24 KiB
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]//
|