summaryrefslogtreecommitdiff
path: root/ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c
diff options
context:
space:
mode:
Diffstat (limited to 'ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c')
-rw-r--r--ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c189
1 files changed, 189 insertions, 0 deletions
diff --git a/ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c b/ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c
new file mode 100644
index 0000000..80a1ffb
--- /dev/null
+++ b/ReferenceCode/Chipset/SystemAgent/SaInit/Pei/SaOcInit.c
@@ -0,0 +1,189 @@
+/** @file
+ OC System Agent Early Post initializations.
+
+@copyright
+ Copyright (c) 2011 - 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+
+///
+/// External include files do NOT need to be explicitly specified in real EDKII
+/// environment
+///
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#include "EdkIIGluePeim.h"
+#include "SaOcInit.h"
+#endif
+
+EFI_STATUS
+SaOcInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN SA_PLATFORM_POLICY_PPI *SaPlatformPolicyPpi
+ )
+/**
+ Initializes Overclocking settings in the processor.
+
+ @param[in] PeiServices - General purpose services available to every PEIM.
+ @param[in] OverclockingtConfig Pointer to Policy protocol instance
+
+ @retval EFI_SUCCESS
+**/
+{
+ EFI_STATUS Status;
+ OC_CAPABILITIES_ITEM OcCaps;
+ VOLTAGE_FREQUENCY_ITEM CurrentVfItem;
+ VOLTAGE_FREQUENCY_ITEM RequestedVfItem;
+ UINT32 LibStatus;
+ UINT8 DomainId;
+ BOOLEAN VfUpdateNeeded;
+ WDT_PPI *gWdtPei;
+
+ LibStatus = 0;
+ VfUpdateNeeded = FALSE;
+
+ if (SaPlatformPolicyPpi->OcConfig->OcSupport == 0){
+ ///
+ /// Overclocking is disabled
+ ///
+ DEBUG ((EFI_D_ERROR, "(OC) Overclocking is disabled. Bypassing SA overclocking flow.\n"));
+ return EFI_SUCCESS;
+ }
+
+ Status = EFI_SUCCESS;
+ ZeroMem(&CurrentVfItem,sizeof(CurrentVfItem));
+ ZeroMem(&RequestedVfItem,sizeof(RequestedVfItem));
+
+ //
+ // Locate WDT_PPI (ICC WDT PPI)
+ //
+ Status = PeiServicesLocatePpi (
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ (VOID **) &gWdtPei
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// We will loop on the CPU domains to manage the voltage/frequency settings
+ ///
+ for (DomainId = OC_LIB_DOMAIN_ID_GT; DomainId <= OC_LIB_DOMAIN_ID_IOD; DomainId++) {
+ ///
+ /// Only GT, Uncore, IOA, and IOD are valid for System Agent
+ ///
+ if ((DomainId == OC_LIB_DOMAIN_ID_GT) ||(DomainId == OC_LIB_DOMAIN_ID_UNCORE) ||
+ (DomainId == OC_LIB_DOMAIN_ID_IOA) || (DomainId == OC_LIB_DOMAIN_ID_IOD)){
+ ///
+ /// Get OC Capabilities of the domain
+ ///
+ ZeroMem(&OcCaps,sizeof(OcCaps));
+ OcCaps.DomainId = DomainId;
+ Status = GetOcCapabilities(&OcCaps,&LibStatus);
+
+ if (LibStatus == OC_LIB_COMPLETION_CODE_SUCCESS){
+ ///
+ /// If any OC is supported on this domain, then proceed
+ ///
+ if (OcCaps.RatioOcSupported || OcCaps.VoltageOverridesSupported || OcCaps.VoltageOffsetSupported){
+ ///
+ /// Need to populate the user requested settings from the platform policy
+ /// to determine if OC changes are desired.
+ ///
+ ZeroMem(&CurrentVfItem,sizeof(CurrentVfItem));
+ CurrentVfItem.DomainId = DomainId;
+
+ ///
+ /// Get a copy of the current domain VfSettings from the Mailbox Library
+ ///
+ Status = GetVoltageFrequencyItem(&CurrentVfItem,&LibStatus);
+ if ((Status != EFI_SUCCESS) || (LibStatus != OC_LIB_COMPLETION_CODE_SUCCESS)){
+ continue;
+ }
+
+ ///
+ /// Populate the user requested VfSettings struct
+ ///
+ ZeroMem(&RequestedVfItem,sizeof(RequestedVfItem));
+ RequestedVfItem.DomainId = DomainId;
+ if (DomainId == OC_LIB_DOMAIN_ID_GT){
+ RequestedVfItem.VfSettings.MaxOcRatio = (UINT8) SaPlatformPolicyPpi->OcConfig->GtMaxOcTurboRatio;
+
+ ///
+ /// VoltageTarget has 2 uses and we need to update the target based
+ /// on the voltagemode requested
+ ///
+ RequestedVfItem.VfSettings.VoltageTargetMode = SaPlatformPolicyPpi->OcConfig->GtVoltageMode;
+ if (RequestedVfItem.VfSettings.VoltageTargetMode == OC_LIB_OFFSET_ADAPTIVE){
+ RequestedVfItem.VfSettings.VoltageTarget = SaPlatformPolicyPpi->OcConfig->GtExtraTurboVoltage;
+ }
+ else {
+ RequestedVfItem.VfSettings.VoltageTarget = SaPlatformPolicyPpi->OcConfig->GtVoltageOverride;
+ }
+ RequestedVfItem.VfSettings.VoltageOffset = SaPlatformPolicyPpi->OcConfig->GtVoltageOffset;
+
+ VfUpdateNeeded = (BOOLEAN)CompareMem((VOID*)&RequestedVfItem,(VOID*)&CurrentVfItem,sizeof(VOLTAGE_FREQUENCY_ITEM));
+ }
+ else if ((DomainId == OC_LIB_DOMAIN_ID_UNCORE) || (DomainId == OC_LIB_DOMAIN_ID_IOA) || (DomainId == OC_LIB_DOMAIN_ID_IOD)){
+ ///
+ /// Uncore,IOA, and IOD domains only supports voltage offset, other settings are ignored
+ ///
+ switch (DomainId) {
+ case OC_LIB_DOMAIN_ID_UNCORE:
+ RequestedVfItem.VfSettings.VoltageOffset = SaPlatformPolicyPpi->OcConfig->SaVoltageOffset;
+ break;
+
+ case OC_LIB_DOMAIN_ID_IOA:
+ RequestedVfItem.VfSettings.VoltageOffset = SaPlatformPolicyPpi->OcConfig->IoaVoltageOffset;
+ break;
+
+ case OC_LIB_DOMAIN_ID_IOD:
+ RequestedVfItem.VfSettings.VoltageOffset = SaPlatformPolicyPpi->OcConfig->IodVoltageOffset;
+ break;
+ }
+
+ if (RequestedVfItem.VfSettings.VoltageOffset != CurrentVfItem.VfSettings.VoltageOffset)
+ VfUpdateNeeded = TRUE;
+ }
+
+ if (VfUpdateNeeded){
+ VfUpdateNeeded = FALSE;
+
+ ///
+ /// Arm watchdog timer for OC changes
+ ///
+ Status = gWdtPei->ReloadAndStart (WDT_TIMEOUT_BETWEEN_PEI_DXE);
+
+ ///
+ /// Need to update the requested voltage/frequency values
+ ///
+ Status = SetVoltageFrequencyItem(RequestedVfItem,&LibStatus);
+ if ((Status != EFI_SUCCESS) || (LibStatus != OC_LIB_COMPLETION_CODE_SUCCESS)){
+ DEBUG ((EFI_D_ERROR, "(OC) Set Voltage Frequency failed. EFI Status = %X, Library Status = %X\n", Status, LibStatus));
+ }
+ }
+ }
+ else {
+ DEBUG ((EFI_D_INFO, "(OC) No OC support for this Domain = %X\n", DomainId));
+ }
+ }
+ else {
+ DEBUG ((EFI_D_ERROR, "(OC) GetOcCapabilities message failed. Library Status = %X, Domain = %X\n", LibStatus, DomainId));
+ }
+ }
+ }
+
+ return Status;
+}