/** @file
Install Platform Clocks Config Data.
@copyright
Copyright 2017 - 2021 Intel Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "PeiCommonBoardInitLib.h"
#include
#include
#include
#include
#include
#include
//
// Table providing details on clocks supported by this library
//
// It is critical that this table be properly constructed.
// The table entries must line up with the clock generatory types
//
CLOCK_GENERATOR_DETAILS mSupportedClockGeneratorTable[] = {
{
ClockGeneratorCk410,
CK410_GENERATOR_ID,
CK410_GENERATOR_SPREAD_SPECTRUM_BYTE,
CK410_GENERATOR_SPREAD_SPECTRUM_BIT
},
{
ClockGeneratorCk420,
CK420_GENERATOR_ID,
CK420_GENERATOR_SPREAD_SPECTRUM_BYTE,
CK420_GENERATOR_SPREAD_SPECTRUM_BIT
},
{
ClockGeneratorCk440,
CK440_GENERATOR_ID,
CK440_GENERATOR_SPREAD_SPECTRUM_BYTE,
CK440_GENERATOR_SPREAD_SPECTRUM_BIT
},
{
ClockGeneratorCk505,
CK505_GENERATOR_ID,
CK505_GENERATOR_SPREAD_SPECTRUM_BYTE,
CK505_GENERATOR_SPREAD_SPECTRUM_BIT
}
};
/**
Configure the clock generator and enable Spread Spectrum if applicable.
@param None
@retval EFI_SUCCESS The function completed successfully.
@retval EFI_UNSUPPORTED Clock generator configuration is not supported
**/
EFI_STATUS
PlatformClocksConfigCallback (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
IN VOID *Ppi
)
{
EFI_STATUS Status;
CLOCKING_MODES ClockingMode;
UINT8 *ConfigurationTable;
UINT8 ConfigurationTablePlatformSRP[] = CLOCK_GENERATOR_SETTINGS_PLATFORMSRP;
UINT8 ConfigurationTableCK505[] = CLOCK_GENERATOR_SETTINGS_CK505;
UINTN Length;
CLOCK_GENERATOR_TYPE ClockType;
BOOLEAN SecondarySmbus = FALSE;
BOOLEAN EnableSpreadSpectrum;
PCH_POLICY_PPI *PchPolicyPpi;
UINT8 ClockGeneratorAddress = 0;
DYNAMIC_SI_LIBARY_PPI *DynamicSiLibraryPpi = NULL;
Status = PeiServicesLocatePpi (&gDynamicSiLibraryPpiGuid, 0, NULL, &DynamicSiLibraryPpi);
if (EFI_ERROR(Status)) {
DEBUG ((DEBUG_ERROR, "ConfigurePlatformClocks. Can not read gDynamicSiLibraryPpiGuid\n"));
return Status;
}
ClockGeneratorAddress = PcdGet8 (PcdOemSkuClockGeneratorAddress);
ClockingMode = InternalAlternate;
Status = EFI_SUCCESS;
if (EFI_ERROR (Status)) {
if (Status != EFI_UNSUPPORTED) {
DEBUG ((DEBUG_ERROR, "ConfigurePlatformClocks. Can't read clock mode! EFI_STATUS = %r\n", Status));
}
return Status;
}
if (External == ClockingMode)
{
DEBUG ((DEBUG_INFO, "ConfigurePlatformClocks. Clock Mode: External\n"));
//
// If the clocking mode is external and CPX is present, then no further configuration of the
// clock is supported at this time.
//
if (DynamicSiLibraryPpi->IsCpuAndRevision (CPU_CPX, REV_ALL)) {
return EFI_UNSUPPORTED;
}
if (DynamicSiLibraryPpi->IsSimicsEnvironment()) {
//
// Simics implements CK505 model
//
ConfigurationTable = ConfigurationTableCK505;
Length = sizeof (ConfigurationTableCK505);
ClockType = ClockGeneratorCk505;
}
else {
//
// SRP/DVP configuration
//
ConfigurationTable = ConfigurationTablePlatformSRP;
Length = sizeof (ConfigurationTablePlatformSRP);
ClockType = ClockGeneratorCk420;
}
Status = (*PeiServices)->LocatePpi (PeiServices,
&gPchPlatformPolicyPpiGuid,
0,
NULL,
(VOID **)&PchPolicyPpi
);
ASSERT_EFI_ERROR (Status);
EnableSpreadSpectrum = (BOOLEAN) PchPolicyPpi->PchConfig.EnableClockSpreadSpec;
if (1 == EnableSpreadSpectrum) {
ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] |= mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset;
} else {
ConfigurationTable[mSupportedClockGeneratorTable[ClockType].SpreadSpectrumByteOffset] &= ~(mSupportedClockGeneratorTable[ClockType].SpreadSpectrumBitOffset);
}
Status = ConfigureClockGenerator (PeiServices,
ClockType,
ClockGeneratorAddress,
Length,
ConfigurationTable,
EnableSpreadSpectrum,
&mSupportedClockGeneratorTable[ClockType],
SecondarySmbus
);
ASSERT_EFI_ERROR (Status);
}
return EFI_SUCCESS;
}
PLATFORM_CLOCKS_CONFIG_TABLE PlatformClocksConfigTable =
{
PLATFORM_CLOCKS_CONFIG_SIGNATURE,
PLATFORM_CLOCKS_CONFIG_VERSION,
PlatformClocksConfigCallback
};
EFI_STATUS
InstallPlatformClocksConfigData (
IN UBA_CONFIG_DATABASE_PPI *UbaConfigPpi
)
{
EFI_STATUS Status = EFI_SUCCESS;
Status = UbaConfigPpi->AddData (
UbaConfigPpi,
&gPlatformClocksConfigDataGuid,
&PlatformClocksConfigTable,
sizeof(PlatformClocksConfigTable)
);
return Status;
}