/** * Callback to Enable IOAPIC on GNB * * * * @param[in] Descriptor Silicon descriptor * @param[in] Buffer Pointer to buffer * @param[in] Pcie Pointer to global PCIe configuration * @retval AGESA_STATUS */ AGESA_STATUS IoapicEnableCallbackV5 ( IN PCIe_DESCRIPTOR_HEADER *Descriptor, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCI_ADDR GnbPciAddress; D0F0xFC_x00_STRUCT D0F0xFC_x00; UINT32 *AddressPtr; UINT32 AddressLow; UINT32 AddressHigh; D0F0xFC_x00.Value = 0x0; D0F0xFC_x00.Field.IoapicEnable = 1; // Set the extended ID enable (default) D0F0xFC_x00.Field.IoapicIdExtEn = 1; // Enable SB feature for every APIC. ACPI OS may disable this once the OS boots D0F0xFC_x00.Field.IoapicSbFeatureEn = 1; AddressPtr = (UINT32*) Buffer; AddressLow = AddressPtr[0] & 0xFFFFFF00; AddressHigh = AddressPtr[1]; // Get the PCI address of the GNB GnbPciAddress = GnbGetHostPciAddress (GnbGetHandle (GnbLibGetHeader (Pcie))); // If the BLDCFG base address is null, assume that the base address of the APIC has already been programmed // If base address is defined in BLDCFG, program it here if ((AddressLow != NULL) || (AddressHigh != NULL)) { GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x01_ADDRESS, AccessS3SaveWidth32, &AddressLow, GnbLibGetHeader (Pcie) ); GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x02_ADDRESS, AccessS3SaveWidth32, &AddressHigh, GnbLibGetHeader (Pcie) ); IDS_HDT_CONSOLE (GNB_TRACE, "GNB IOAPIC base address is at high %x, low %x\n", AddressHigh, AddressLow); // Enable the IOAPIC. GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x00_ADDRESS, AccessS3SaveWidth32, &D0F0xFC_x00.Value, GnbLibGetHeader (Pcie) ); } return AGESA_SUCCESS; }
/** * Request Pcie voltage change * * * * @param[in] VidIndex The request VID index * @param[in] StdHeader Standard configuration header */ VOID PcieSiliconRequestVoltage ( IN UINT8 VidIndex, IN AMD_CONFIG_PARAMS *StdHeader ) { D0F0x64_x6A_STRUCT D0F0x64_x6A; D0F0x64_x6B_STRUCT D0F0x64_x6B; //Enable voltage client GnbLibPciIndirectRead ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x6A.Value, StdHeader ); D0F0x64_x6A.Field.VoltageChangeEn = 0x1; GnbLibPciIndirectWrite ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x6A.Value, StdHeader ); D0F0x64_x6A.Field.VoltageLevel = VidIndex; D0F0x64_x6A.Field.VoltageChangeReq = !D0F0x64_x6A.Field.VoltageChangeReq; GnbLibPciIndirectWrite ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), D0F0x64_x6A_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x6A.Value, StdHeader ); do { GnbLibPciIndirectRead ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), D0F0x64_x6B_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x6B.Value, StdHeader ); } while (D0F0x64_x6A.Field.VoltageChangeReq != D0F0x64_x6B.Field.VoltageChangeAck); }
/** * Request Pcie voltage change * * * * @param[in] VidIndex The request VID index * @param[in] StdHeader Standard configuration header */ VOID PcieSiliconRequestVoltage ( IN UINT8 VidIndex, IN AMD_CONFIG_PARAMS *StdHeader ) { ex488_STRUCT ex488 ; ex489_STRUCT ex489 ; //Enable voltage client GnbLibPciIndirectRead ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), 0x6a | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &ex488.Value, StdHeader ); ex488.Field.VoltageChangeEn = 0x1; GnbLibPciIndirectWrite ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), 0x6a | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &ex488.Value, StdHeader ); ex488.Field.VoltageLevel = VidIndex; ex488.Field.VoltageChangeReq = !ex488.Field.VoltageChangeReq; GnbLibPciIndirectWrite ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), 0x6a | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &ex488.Value, StdHeader ); do { GnbLibPciIndirectRead ( MAKE_SBDFO (0, 0, 0, 0, D0F0x60_ADDRESS), 0x6b | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &ex489.Value, StdHeader ); } while (ex488.Field.VoltageChangeReq != ex489.Field.VoltageChangeAck); }
VOID STATIC IoapicInitCallbackV5 ( IN PCIe_ENGINE_CONFIG *Engine, IN OUT VOID *Buffer, IN PCIe_PLATFORM_CONFIG *Pcie ) { PCI_ADDR GnbPciAddress; D0F0xFC_x10_STRUCT D0F0xFC_x10; GnbPciAddress = GnbGetHostPciAddress ((GNB_HANDLE *) PcieConfigGetParent (DESCRIPTOR_SILICON, &Engine->Header)); D0F0xFC_x10.Value = 0x0; // Bounds check values - make sure the value is small enough to fit the field size ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap < (1 << D0F0xFC_x10_BrExtIntrGrp_WIDTH)); ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle < (1 << D0F0xFC_x10_BrExtIntrSwz_WIDTH)); ASSERT (Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt < (1 << D0F0xFC_x10_BrIntIntrMap_WIDTH)); // Get the configuration from the PCIe_PORT_DATA APIC_DEVICE_INFO struct D0F0xFC_x10.Field.BrExtIntrGrp = Engine->Type.Port.PortData.ApicDeviceInfo.GroupMap; D0F0xFC_x10.Field.BrExtIntrSwz = Engine->Type.Port.PortData.ApicDeviceInfo.Swizzle; D0F0xFC_x10.Field.BrIntIntrMap = Engine->Type.Port.PortData.ApicDeviceInfo.BridgeInt; // Write the register GnbLibPciIndirectWrite ( GnbPciAddress.AddressValue | D0F0xF8_ADDRESS, D0F0xFC_x10_ADDRESS + Engine->Type.Port.LogicalBridgeId, AccessS3SaveWidth32, &D0F0xFC_x10.Value, GnbLibGetHeader (Pcie) ); }
VOID GnbSmuServiceRequestV4 ( IN PCI_ADDR GnbPciAddress, IN UINT8 RequestId, IN UINT32 AccessFlags, IN AMD_CONFIG_PARAMS *StdHeader ) { D0F0xBC_xE0003004_STRUCT D0F0xBC_xE0003004; D0F0xBC_xE0003000_STRUCT D0F0xBC_xE0003000; IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuServiceRequestV4 Enter\n"); IDS_HDT_CONSOLE (NB_MISC, " Service Request %d\n", RequestId); if ((AccessFlags & GNB_REG_ACC_FLAG_S3SAVE) != 0) { SMU_MSG_CONTEXT SmuMsgContext; SmuMsgContext.GnbPciAddress.AddressValue = GnbPciAddress.AddressValue; SmuMsgContext.RequestId = RequestId; S3_SAVE_DISPATCH (StdHeader, GnbSmuServiceRequestV4S3Script_ID, sizeof (SmuMsgContext), &SmuMsgContext); } do { GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0003004_ADDRESS, AccessWidth32, &D0F0xBC_xE0003004.Value, StdHeader); } while (D0F0xBC_xE0003004.Field.IntDone == 0x0); GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0003000_ADDRESS, AccessWidth32, &D0F0xBC_xE0003000.Value, StdHeader); D0F0xBC_xE0003000.Field.IntToggle = ~D0F0xBC_xE0003000.Field.IntToggle; D0F0xBC_xE0003000.Field.ServiceIndex = RequestId; GnbLibPciIndirectWrite (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0003000_ADDRESS, AccessWidth32, &D0F0xBC_xE0003000.Value, StdHeader); do { GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0003004_ADDRESS, AccessWidth32, &D0F0xBC_xE0003004.Value, StdHeader); } while (D0F0xBC_xE0003004.Field.IntAck == 0x0); do { GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0003004_ADDRESS, AccessWidth32, &D0F0xBC_xE0003004.Value, StdHeader); } while (D0F0xBC_xE0003004.Field.IntDone == 0x0); IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuServiceRequestV4 Exit\n"); }
AGESA_STATUS GnbSmuFirmwareLoadV4 ( IN PCI_ADDR GnbPciAddress, IN FIRMWARE_HEADER_V4 *Firmware, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT32 Index; D0F0xBC_xE00030A4_STRUCT D0F0xBC_xE00030A4; D0F0xBC_xE0000004_STRUCT D0F0xBC_xE0000004; D0F0xBC_xE0003088_STRUCT D0F0xBC_xE0003088; D0F0xBC_x80010000_STRUCT D0F0xBC_x80010000; D0F0xBC_x1F380_STRUCT D0F0xBC_x1F380; IDS_HDT_CONSOLE (GNB_TRACE, "GnbSmuFirmwareLoadV4 Enter\n"); IDS_HDT_CONSOLE (NB_MISC, " Firmware version 0x%x\n", Firmware->Version); IDS_OPTION_HOOK (IDS_REPORT_SMU_FW_VERSION, &(Firmware->Version), StdHeader); // Step 2, 10, make sure Rom firmware sequence is done do { GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE0000004_ADDRESS, AccessWidth32, &D0F0xBC_xE0000004.Value, StdHeader); } while (D0F0xBC_xE0000004.Field.boot_seq_done == 0); // Step 1, check if firmware running in protected mode GnbLibPciIndirectRead (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_xE00030A4_ADDRESS, AccessWidth32, &D0F0xBC_xE00030A4.Value, StdHeader); if (D0F0xBC_xE00030A4.Field.SmuProtectedMode == 0) { // Step3, Clear firmware interrupt flags GnbLibPciIndirectRMW ( GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_x1F380_ADDRESS, AccessWidth32, 0x0, 0x0, StdHeader ); } //Step 4, 11, Assert LM32 reset GnbLibPciIndirectRMW ( GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, D0F0xBC_x80000000_ADDRESS, AccessWidth32, (UINT32) ~(D0F0xBC_x80000000_lm32_rst_reg_MASK), 1 << D0F0xBC_x80000000_lm32_rst_reg_OFFSET, StdHeader ); // Step5, 12, Load firmware for (Index = 0; Index < (Firmware->FirmwareLength + Firmware->HeaderLength); Index++) { GnbLibPciIndirectWrite (GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, SMC_RAM_START_ADDR + (Index * 4), AccessWidth32, &((UINT32 *) Firmware)[Index], StdHeader); } if (D0F0xBC_xE00030A4.Field.SmuProtectedMode == 0) { //Step 6, Write jmp to RAM firmware GnbLibPciIndirectRMW ( GnbPciAddress.AddressValue | D0F0xB8_ADDRESS, 0x0, AccessWidth32, 0x0, 0xE0000000 + ((SMC_RAM_START_ADDR + Firmware->HeaderLength * 4) >> 2), StdHeader ); } else {
/** * Gnb Unified Register Access method * * * @param[in] Device Pointer to Device object * @param[in] UraTokenInfo Pointer to URA_TOKEN_INFO structure * @param[in, out] Value Pointer to Context */ VOID GnbUraSetML ( IN DEV_OBJECT *Device, IN URA_TOKEN_INFO *UraTokenInfo, IN OUT VOID *Value ) { ACCESS_WIDTH Width; UINT32 RegValue; UINT32 TargetValue; UINT32 FieldMask; UINT32 TempValue; Width = (UraTokenInfo->Flags == GNB_URA_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; FieldMask = 0; TempValue = *(UINT32 *)Value; switch (UraTokenInfo->MethodType) { case TYPE_GNB_INDIRECT_ACCESS: if (UraTokenInfo->WholeRegAccess == TRUE) { TargetValue = TempValue; } else { GnbLibPciIndirectRead ( Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, Width, &RegValue, Device->StdHeader); FieldMask = (((UINT32)1 << UraTokenInfo->BfWidth) - 1); TargetValue = RegValue & (~(FieldMask << UraTokenInfo->BfOffset)); TargetValue |= (TempValue & FieldMask) << UraTokenInfo->BfOffset; } GnbLibPciIndirectWrite ( Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, Width, &TargetValue, Device->StdHeader); IDS_HDT_CONSOLE (NB_MISC, " Ura SET: RegDomainType = 0x%x IndirectAddress = 0x%08x, Value = 0x%08x\n", UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, TargetValue); break; case TYPE_GNB_PROTOCOL_ACCESS: if (UraTokenInfo->WholeRegAccess == TRUE) { TargetValue = TempValue; } else { GnbRegisterReadML (Device->GnbHandle, UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, &RegValue, UraTokenInfo->Flags, Device->StdHeader); FieldMask = (((UINT32)1 << UraTokenInfo->BfWidth) - 1); TargetValue = RegValue & (~(FieldMask << UraTokenInfo->BfOffset)); TargetValue |= (TempValue & FieldMask) << UraTokenInfo->BfOffset; } GnbRegisterWriteML (Device->GnbHandle, UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, &TargetValue, UraTokenInfo->Flags, Device->StdHeader); IDS_HDT_CONSOLE (NB_MISC, " Ura SET: RegDomainType = %d, Address = 0x%08x, Value = 0x%08x\n", UraTokenInfo->RegDomainType, UraTokenInfo->RegAddress, TargetValue); break; default: ASSERT (FALSE); break; } }
/** * Gnb Unified Register Access method * * * @param[in] Device Pointer to device object * @param[in] UraTokenInfo Pointer to URA_TOKEN_INFO structure * @param[in, out] UraTuple Pointer to structure URA_TUPLE * @param[in] CombinedCount Token count */ VOID GnbUraStreamSetML ( IN DEV_OBJECT *Device, IN URA_TOKEN_INFO *UraTokenInfo, IN OUT URA_TUPLE *UraTuple, IN UINT32 CombinedCount ) { ACCESS_WIDTH Width; UINT32 RegValue; UINT32 Index; UINT32 StreamSetAddress; UINT32 StepLength; UINT32 TargetAddress; Width = (UraTokenInfo->Flags == GNB_URA_FLAG_S3SAVE) ? AccessS3SaveWidth32 : AccessWidth32; StreamSetAddress = UraTokenInfo->RegAddress; StepLength = UraTuple->StepLength; for (Index = 0; Index < CombinedCount; Index++) { RegValue = *(((UINT32 *) ((UINTN)UraTuple->Value)) + Index); switch (UraTokenInfo->MethodType) { case TYPE_GNB_INDIRECT_ACCESS: TargetAddress = Device->DevPciAddress.AddressValue | UraTokenInfo->RegDomainType; //IDS_HDT_CONSOLE (NB_MISC, "0x%08x:0x%08x, \n", StreamSetAddress, RegValue); GnbLibPciIndirectWrite (TargetAddress, StreamSetAddress, Width, &RegValue, Device->StdHeader); break; case TYPE_GNB_PROTOCOL_ACCESS: TargetAddress = UraTokenInfo->RegDomainType; GnbRegisterWriteML (Device->GnbHandle, (UINT8)TargetAddress, StreamSetAddress, &RegValue, UraTokenInfo->Flags, Device->StdHeader); break; default: ASSERT (FALSE); return; } StreamSetAddress += StepLength; } }
/** * Entry point for enabling Power Status Indicator * * This function must be run after all P-State routines have been executed * * @param[in] PsiServices The current CPU's family services. * @param[in] EntryPoint Timepoint designator. * @param[in] PlatformConfig Contains the runtime modifiable feature input data. * @param[in] StdHeader Config handle for library and services. * * @retval AGESA_SUCCESS Always succeeds. * */ AGESA_STATUS STATIC F15CzInitializePsi ( IN PSI_FAMILY_SERVICES *PsiServices, IN UINT64 EntryPoint, IN PLATFORM_CONFIGURATION *PlatformConfig, IN AMD_CONFIG_PARAMS *StdHeader ) { PCI_ADDR PciAddress; CPU_SPECIFIC_SERVICES *FamilySpecificServices; UINT32 HwPstateMaxVal; F15_CZ_CLK_PWR_TIMING_CTRL2_REGISTER ClkPwrTimingCtrl2; UINT32 CoreVrmLowPowerThreshold; UINT32 Pstate; UINT32 PstateCurrent; UINT32 NextPstateCurrent; PSTATE_MSR PstateMsr; UINT32 CurrentVid; UINT32 PreviousVid; NB_PSTATE_REGISTER NbPstateReg; NB_PSTATE_CTRL_REGISTER NbPsCtrl; UINT32 NbVrmLowPowerThreshold; UINT32 NbPstate; UINT32 NbPstateMaxVal; UINT32 NbPstateCurrent; UINT32 NextNbPstateCurrent; UINT32 PreviousNbVid; UINT32 CurrentNbVid; SMUSVI_MISC_VID_STATUS_REGISTER SmuSviMiscVidStatus; SMUSVI_POWER_CONTROL_MISC_REGISTER SmuSviPowerCtrlMisc; if ((EntryPoint & (CPU_FEAT_AFTER_POST_MTRR_SYNC | CPU_FEAT_AFTER_RESUME_MTRR_SYNC)) != 0) { // Configure PsiVid GetCpuServicesOfCurrentCore ((CONST CPU_SPECIFIC_SERVICES **) &FamilySpecificServices, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " F15CzPmVrmLowPowerModeEnable\n"); if (PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold != 0) { // Set up PSI0_L for VDD CoreVrmLowPowerThreshold = PlatformConfig->VrmProperties[CoreVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " Core VRM - LowPowerThreshold: %d \n", CoreVrmLowPowerThreshold); PreviousVid = 0xFF; PciAddress.AddressValue = CPTC2_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &ClkPwrTimingCtrl2, StdHeader); HwPstateMaxVal = ClkPwrTimingCtrl2.HwPstateMaxVal; IDS_HDT_CONSOLE (CPU_TRACE, " HwPstateMaxVal %d\n", HwPstateMaxVal); for (Pstate = 0; Pstate <= HwPstateMaxVal; Pstate++) { // Check only valid P-state if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) Pstate, &PstateCurrent, StdHeader) != TRUE) { continue; } LibAmdMsrRead ((UINT32) (Pstate + PS_REG_BASE), (UINT64 *) &PstateMsr, StdHeader); CurrentVid = (UINT32) PstateMsr.CpuVid; if (Pstate == HwPstateMaxVal) { NextPstateCurrent = 0; } else { // Check P-state from P1 to HwPstateMaxVal if (FamilySpecificServices->GetProcIddMax (FamilySpecificServices, (UINT8) (Pstate + 1), &NextPstateCurrent, StdHeader) != TRUE) { continue; } } if ((PstateCurrent <= CoreVrmLowPowerThreshold) && (NextPstateCurrent <= CoreVrmLowPowerThreshold) && (CurrentVid != PreviousVid)) { // Program PsiVid and PsiVidEn if PSI state is found and stop searching. GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader); SmuSviPowerCtrlMisc.PSIVID = CurrentVid; SmuSviPowerCtrlMisc.PSIVIDEN = 1; GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_POWER_CONTROL_MISC, AccessWidth32, &SmuSviPowerCtrlMisc, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " PsiVid is enabled at P-state %d. PsiVid: %d\n", Pstate, CurrentVid); break; } else { PreviousVid = CurrentVid; } } } if (PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold != 0) { // Set up NBPSI0_L for VDDNB NbVrmLowPowerThreshold = PlatformConfig->VrmProperties[NbVrm].LowPowerThreshold; IDS_HDT_CONSOLE (CPU_TRACE, " NB VRM - LowPowerThreshold: %d\n", NbVrmLowPowerThreshold); PreviousNbVid = 0xFF; PciAddress.AddressValue = NB_PSTATE_CTRL_PCI_ADDR; LibAmdPciRead (AccessWidth32, PciAddress, &NbPsCtrl, StdHeader); NbPstateMaxVal = NbPsCtrl.NbPstateMaxVal; ASSERT (NbPstateMaxVal < NM_NB_PS_REG); IDS_HDT_CONSOLE (CPU_TRACE, " NbPstateMaxVal %d\n", NbPstateMaxVal); for (NbPstate = 0; NbPstate <= NbPstateMaxVal; NbPstate++) { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) NbPstate, &NbPstateCurrent, StdHeader) != TRUE) { continue; } PciAddress.Address.Register = (NB_PSTATE_0 + (sizeof (NB_PSTATE_REGISTER) * NbPstate)); LibAmdPciRead (AccessWidth32, PciAddress, &NbPstateReg, StdHeader); CurrentNbVid = (UINT32) GetF15CzNbVid (&NbPstateReg); if (NbPstate == NbPstateMaxVal) { NextNbPstateCurrent = 0; } else { // Check only valid NB P-state if (FamilySpecificServices->GetNbIddMax (FamilySpecificServices, (UINT8) (NbPstate + 1), &NextNbPstateCurrent, StdHeader) != TRUE) { continue; } } if ((NbPstateCurrent <= NbVrmLowPowerThreshold) && (NextNbPstateCurrent <= NbVrmLowPowerThreshold) && (CurrentNbVid != PreviousNbVid)) { // Program NbPsi0Vid and NbPsi0VidEn if PSI state is found and stop searching. GnbLibPciIndirectRead (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader); SmuSviMiscVidStatus.NB_PSI_VID = CurrentNbVid; SmuSviMiscVidStatus.NB_PSI_VID_EN = 1; GnbLibPciIndirectWrite (MAKE_SBDFO (0, 0, 0, 0, 0xB8), SMUSVI_MISC_VID_STATUS, AccessWidth32, &SmuSviMiscVidStatus, StdHeader); IDS_HDT_CONSOLE (CPU_TRACE, " NbPsi0Vid is enabled at NB P-state %d. NbPsi0Vid: %d\n", NbPstate, CurrentNbVid); break; } else { PreviousNbVid = CurrentNbVid; } } } } return AGESA_SUCCESS; }
VOID NbInitIocClockGating ( IN NB_CLK_GATING_CTRL *NbClkGatingCtrl, IN GNB_PLATFORM_CONFIG *Gnb ) { BOOLEAN Ioc_Lclk_Gating; BOOLEAN Ioc_Sclk_Gating; D0F0x64_x22_STRUCT D0F0x64_x22; D0F0x64_x23_STRUCT D0F0x64_x23; D0F0x64_x24_STRUCT D0F0x64_x24; FCRxFF30_01F5_STRUCT FCRxFF30_01F5; Ioc_Lclk_Gating = NbClkGatingCtrl->Ioc_Lclk_Gating; Ioc_Sclk_Gating = NbClkGatingCtrl->Ioc_Sclk_Gating; //D0F0x64_x22 GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x22_ADDRESS | IOC_WRITE_ENABLE, AccessWidth32, &D0F0x64_x22.Value, Gnb->StdHeader ); D0F0x64_x22.Field.SoftOverrideClk4 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x22.Field.SoftOverrideClk3 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x22.Field.SoftOverrideClk2 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x22.Field.SoftOverrideClk1 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x22.Field.SoftOverrideClk0 = Ioc_Lclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x22_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x22.Value, Gnb->StdHeader ); //D0F0x64_x23 GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x23_ADDRESS | IOC_WRITE_ENABLE, AccessWidth32, &D0F0x64_x23.Value, Gnb->StdHeader ); D0F0x64_x23.Field.SoftOverrideClk4 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x23.Field.SoftOverrideClk3 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x23.Field.SoftOverrideClk2 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x23.Field.SoftOverrideClk1 = Ioc_Lclk_Gating ? 0 : 1; D0F0x64_x23.Field.SoftOverrideClk0 = Ioc_Lclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x23_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x23.Value, Gnb->StdHeader ); //D0F0x64_x24 GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x24_ADDRESS | IOC_WRITE_ENABLE, AccessWidth32, &D0F0x64_x24.Value, Gnb->StdHeader ); D0F0x64_x24.Field.SoftOverrideClk1 = Ioc_Sclk_Gating ? 0 : 1; D0F0x64_x24.Field.SoftOverrideClk0 = Ioc_Sclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, D0F0x64_x24_ADDRESS | IOC_WRITE_ENABLE, AccessS3SaveWidth32, &D0F0x64_x24.Value, Gnb->StdHeader ); //FCRxFF30_01F5[CgIocCgttLclkOverride, CgIocCgttSclkOverride] NbSmuSrbmRegisterRead (FCRxFF30_01F5_ADDRESS, &FCRxFF30_01F5.Value, Gnb->StdHeader); FCRxFF30_01F5.Field.CgIocCgttLclkOverride = 0; FCRxFF30_01F5.Field.CgIocCgttSclkOverride = 0; NbSmuSrbmRegisterWrite (FCRxFF30_01F5_ADDRESS, &FCRxFF30_01F5.Value, TRUE, Gnb->StdHeader); }
VOID NbInitOrbClockGating ( IN NB_CLK_GATING_CTRL *NbClkGatingCtrl, IN GNB_PLATFORM_CONFIG *Gnb ) { BOOLEAN Orb_Sclk_Gating; BOOLEAN Orb_Lclk_Gating; D0F0x98_x49_STRUCT D0F0x98_x49; D0F0x98_x4A_STRUCT D0F0x98_x4A; D0F0x98_x4B_STRUCT D0F0x98_x4B; FCRxFF30_01F5_STRUCT FCRxFF30_01F5; Orb_Sclk_Gating = NbClkGatingCtrl->Orb_Sclk_Gating; Orb_Lclk_Gating = NbClkGatingCtrl->Orb_Lclk_Gating; // ORB clock gating (Lclk) //D0F0x98_x4[A:9] GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x49_ADDRESS, AccessWidth32, &D0F0x98_x49.Value, Gnb->StdHeader ); D0F0x98_x49.Field.SoftOverrideClk6 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk5 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk4 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk3 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk2 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk1 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x49.Field.SoftOverrideClk0 = Orb_Lclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x49_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessS3SaveWidth32, &D0F0x98_x49.Value, Gnb->StdHeader ); GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x4A_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessWidth32, &D0F0x98_x4A.Value, Gnb->StdHeader ); D0F0x98_x4A.Field.SoftOverrideClk6 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk5 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk4 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk3 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk2 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk1 = Orb_Lclk_Gating ? 0 : 1; D0F0x98_x4A.Field.SoftOverrideClk0 = Orb_Lclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x4A_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessS3SaveWidth32, &D0F0x98_x4A.Value, Gnb->StdHeader ); //D0F0x98_x4B GnbLibPciIndirectRead ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x4B_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessWidth32, &D0F0x98_x4B.Value, Gnb->StdHeader ); D0F0x98_x4B.Field.SoftOverrideClk = Orb_Sclk_Gating ? 0 : 1; GnbLibPciIndirectWrite ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, D0F0x98_x4B_ADDRESS | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessS3SaveWidth32, &D0F0x98_x4B.Value, Gnb->StdHeader ); //FCRxFF30_01F5[CgOrbCgttLclkOverride, CgOrbCgttSclkOverride] NbSmuSrbmRegisterRead (FCRxFF30_01F5_ADDRESS, &FCRxFF30_01F5.Value, Gnb->StdHeader); FCRxFF30_01F5.Field.CgOrbCgttLclkOverride = 0; FCRxFF30_01F5.Field.CgOrbCgttSclkOverride = 0; NbSmuSrbmRegisterWrite (FCRxFF30_01F5_ADDRESS, &FCRxFF30_01F5.Value, TRUE, Gnb->StdHeader); }