AGESA_STATUS GfxInitAtPost ( IN AMD_CONFIG_PARAMS *StdHeader ) { AMD_POST_PARAMS *PostParamsPtr; GFX_CARD_CARD_INFO GfxDiscreteCardInfo; AGESA_STATUS Status; GFX_PLATFORM_CONFIG *Gfx; PostParamsPtr = (AMD_POST_PARAMS *)StdHeader; IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitAtPost Enter\n"); Status = GfxLocateConfigData (StdHeader, &Gfx); ASSERT (Status == AGESA_SUCCESS); if (Status == AGESA_SUCCESS) { if (GfxLibIsControllerPresent (StdHeader)) { if (PostParamsPtr->MemConfig.UmaMode != UMA_NONE) { LibAmdMemFill (&GfxDiscreteCardInfo, 0x0, sizeof (GfxDiscreteCardInfo), StdHeader); GfxGetDiscreteCardInfo (&GfxDiscreteCardInfo, StdHeader); if (GfxDiscreteCardInfo.PciGfxCardBitmap != 0 || (GfxDiscreteCardInfo.AmdPcieGfxCardBitmap & GfxDiscreteCardInfo.PcieGfxCardBitmap) != GfxDiscreteCardInfo.AmdPcieGfxCardBitmap) { PostParamsPtr->MemConfig.UmaMode = UMA_NONE; IDS_HDT_CONSOLE (GFX_MISC, " GfxDisabled due dGPU policy\n"); } } } else { PostParamsPtr->MemConfig.UmaMode = UMA_NONE; Gfx->GfxFusedOff = TRUE; } } else { PostParamsPtr->MemConfig.UmaMode = UMA_NONE; } IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitAtPost Exit [0x%x]\n", Status); return Status; }
BOOLEAN GnbCableSafeIsSupported ( IN AMD_CONFIG_PARAMS *StdHeader ) { BOOLEAN Result; CPU_LOGICAL_ID LogicalId; SMU_FIRMWARE_REV FirmwareRev; Result = FALSE; if (GfxLibIsControllerPresent (StdHeader)) { GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); FirmwareRev = NbSmuFirmwareRevision (StdHeader); if (SMI_FIRMWARE_REVISION (FirmwareRev) >= 0x010904 && LogicalId.Revision > AMD_F12_LN_A1) { Result = TRUE; } } return Result; }
/** * Build integrated info table * GMC FB access requred * * * @param[in] StdHeader Standard configuration header * @retval AGESA_STATUS */ AGESA_STATUS GfxIntInfoTableInterfaceTN ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS AgesaStatus; AGESA_STATUS Status; GFX_PLATFORM_CONFIG *Gfx; IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInterfaceTN Enter\n"); AgesaStatus = AGESA_SUCCESS; if (GfxLibIsControllerPresent (StdHeader)) { Status = GfxLocateConfigData (StdHeader, &Gfx); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status != AGESA_FATAL) { Status = GfxIntInfoTableInitTN (Gfx); AGESA_STATUS_UPDATE (Status, AgesaStatus); } } IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInterfaceTN Exit[0x%x]\n", AgesaStatus); return AgesaStatus; }
AGESA_STATUS PcieFmAlibBuildAcpiTable ( IN VOID *AlibSsdtPtr, IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; UINT32 AmlObjName; GFX_PLATFORM_CONFIG *Gfx; VOID *AmlObjPtr; BOOLEAN AltVddNbSupport; IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmAlibBuildAcpiTable Enter\n"); AgesaStatus = AGESA_SUCCESS; AltVddNbSupport = TRUE; // AmlObjName = 'A0DA'; AmlObjName = 0x41304441; AmlObjPtr = GnbLibFind (AlibSsdtPtr, ((ACPI_TABLE_HEADER*) &AlibSsdt[0])->TableLength, (UINT8*) &AmlObjName, sizeof (AmlObjName)); ASSERT (AmlObjPtr != NULL); if (AmlObjPtr != NULL) { Status = GfxLocateConfigData (StdHeader, &Gfx); AGESA_STATUS_UPDATE (Status, AgesaStatus); ASSERT (Status == AGESA_SUCCESS); if ((Status != AGESA_SUCCESS) || (GnbBuildOptions.CfgAltVddNb == FALSE) || (Gfx->UmaInfo.MemClock > DDR1333_FREQUENCY) || ((Gfx->GfxDiscreteCardInfo.AmdPcieGfxCardBitmap != 0) && GfxLibIsControllerPresent (StdHeader))) { AltVddNbSupport = FALSE; } // CBS/IDS can change AltVddNbSupport IDS_OPTION_HOOK (IDS_GNB_ALTVDDNB, &AltVddNbSupport, StdHeader); if (!AltVddNbSupport) { IDS_HDT_CONSOLE (GNB_TRACE, " AltVddNb - Disabled\n"); *(UINT8*)((UINT8*) AmlObjPtr + 5) = 0; } } else { AgesaStatus = AGESA_ERROR; } IDS_HDT_CONSOLE (GNB_TRACE, "PcieFmAlibBuildAcpiTable Exit[0x%x]\n", AgesaStatus); return AgesaStatus; }
VOID NbInitLclkDeepSleep ( IN GNB_PLATFORM_CONFIG *Gnb ) { SMUx1B_STRUCT SMUx1B; SMUx1D_STRUCT SMUx1D; UINT32 LclkDpSlpEn; IDS_HDT_CONSOLE (GNB_TRACE, "NbInitLclkDeepSleep Enter\n"); LclkDpSlpEn = GnbBuildOptions.LclkDeepSleepEn ? 1 : 0; NbSmuIndirectRead (SMUx1B_ADDRESS, AccessWidth16, &SMUx1B.Value, Gnb->StdHeader); NbSmuIndirectRead (SMUx1D_ADDRESS, AccessWidth16, &SMUx1D.Value, Gnb->StdHeader); SMUx1B.Field.LclkDpSlpDiv = 5; SMUx1B.Field.LclkDpSlpMask = (GfxLibIsControllerPresent (Gnb->StdHeader) ? (0xFF) : 0xEF); SMUx1B.Field.RampDis = 0; SMUx1D.Field.LclkDpSlpHyst = 0xf; SMUx1D.Field.LclkDpSlpEn = LclkDpSlpEn; IDS_HDT_CONSOLE (GNB_TRACE, " LCLK Deep Sleep [%s]\n", (LclkDpSlpEn != 0) ? "Enabled" : "Disabled"); NbSmuIndirectWrite (SMUx1B_ADDRESS, AccessS3SaveWidth16, &SMUx1B.Value, Gnb->StdHeader); NbSmuIndirectWrite (SMUx1D_ADDRESS, AccessS3SaveWidth16, &SMUx1D.Value, Gnb->StdHeader); IDS_HDT_CONSOLE (GNB_TRACE, "NbInitLclkDeepSleep Exit\n"); }
AGESA_STATUS GfxInitSview ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; AGESA_STATUS AgesaStatus; GFX_PLATFORM_CONFIG *Gfx; UINT32 OriginalCmdReg; IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Enter\n"); AgesaStatus = AGESA_SUCCESS; Status = GfxLocateConfigData (StdHeader, &Gfx); AGESA_STATUS_UPDATE (Status, AgesaStatus); if (Status == AGESA_SUCCESS) { if (GfxLibIsControllerPresent (StdHeader)) { if (!GfxFmIsVbiosPosted (Gfx)) { GFX_VBIOS_IMAGE_INFO VbiosImageInfo; LibAmdMemCopy (&VbiosImageInfo.StdHeader, StdHeader, sizeof (AMD_CONFIG_PARAMS), StdHeader); VbiosImageInfo.ImagePtr = NULL; VbiosImageInfo.GfxPciAddress = Gfx->GfxPciAddress; VbiosImageInfo.Flags = GFX_VBIOS_IMAGE_FLAG_SPECIAL_POST; GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, &OriginalCmdReg, StdHeader); GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0xff, BIT1 | BIT2 | BIT0, StdHeader); Status = AgesaGetVbiosImage (0, &VbiosImageInfo); if (Status == AGESA_SUCCESS && VbiosImageInfo.ImagePtr != NULL) { GfxLibCopyMemToFb (VbiosImageInfo.ImagePtr, 0, (*((UINT8*) VbiosImageInfo.ImagePtr + 2)) << 9, Gfx); } else { GfxFmDisableController (StdHeader); AgesaStatus = AGESA_ERROR; } GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessS3SaveWidth8, 0x00, OriginalCmdReg, StdHeader); } } } IDS_HDT_CONSOLE (GNB_TRACE, "GfxInitSview Exit [0x%x]\n", AgesaStatus); return AgesaStatus; }
/** * Family specific fuse table patch * Is's correct behavior if we would have 4 states, it would be * PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 5 * PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 6 * PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 7 * If we would have 4 states it would be * PP_FUSE_ARRAY->LclkDpmDid[0] - Goes to State 4 * PP_FUSE_ARRAY->LclkDpmDid[1] - Goes to State 5 * PP_FUSE_ARRAY->LclkDpmDid[2] - Goes to State 6 * PP_FUSE_ARRAY->LclkDpmDid[3] - Goes to State 7 * * @param[in] PpFuseArray Pointer to PP_FUSE_ARRAY * @param[in] StdHeader Pointer to AMD_CONFIG_PARAMS */ VOID NbFmFuseAdjustFuseTablePatch ( IN OUT PP_FUSE_ARRAY *PpFuseArray, IN AMD_CONFIG_PARAMS *StdHeader ) { UINT8 LclkDpmMode; UINT8 SwSatateIndex; UINT8 MaxSclkIndex; UINT8 DpmStateIndex; UINT8 CurrentSclkDpmDid; CPU_LOGICAL_ID LogicalId; D18F3x15C_STRUCT D18F3x15C; LclkDpmMode = GnbBuildOptions.LclkDpmEn ? LclkDpmRcActivity : LclkDpmDisabled; GetLogicalIdOfCurrentCore (&LogicalId, StdHeader); if ((LogicalId.Revision & (AMD_F12_LN_A0 | AMD_F12_LN_A1)) != 0) { LclkDpmMode = LclkDpmDisabled; } IDS_OPTION_HOOK (IDS_GNB_LCLK_DPM_EN, &LclkDpmMode, StdHeader); // Read Sclk VID GnbLibPciRead ( MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), AccessWidth32, &D18F3x15C.Value, StdHeader ); PpFuseArray->SclkVid[0] = (UINT8) (D18F3x15C.Field.SclkVidLevel0); PpFuseArray->SclkVid[1] = (UINT8) (D18F3x15C.Field.SclkVidLevel1); PpFuseArray->SclkVid[2] = (UINT8) (D18F3x15C.Field.SclkVidLevel2); PpFuseArray->SclkVid[3] = (UINT8) (D18F3x15C.Field.SclkVidLevel3); //For all CPU rev LclkDpmValid[3] = 0 PpFuseArray->LclkDpmValid[3] = 0; PpFuseArray->LclkDpmVid[3] = 0; PpFuseArray->LclkDpmDid[3] = 0; // For LCLKDPM set LclkDpmVid[0] = 0, no matter if LCLK DMP enable or disable. PpFuseArray->LclkDpmVid[0] = 0; if (LclkDpmMode != LclkDpmRcActivity) { //If LCLK DPM disable (LclkDpmMode != LclkDpmRcActivity) // - LclkDpmDid[1,2] = LclkDpmDid [0], LclkDpmVid[1,2] = LclkDpmVid[0] // - Execute LCLK DPM init PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmVid[2] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0]; PpFuseArray->LclkDpmDid[2] = PpFuseArray->LclkDpmDid[0]; IDS_HDT_CONSOLE (NB_MISC, " F12 LCLK DPM Mode Disable -- use DPM0 fusing\n"); } else { // If LCLK DPM enabled // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage // - Execute LCLK DPM init PpFuseArray->LclkDpmVid[2] = PpFuseArray->PcieGen2Vid; if (GfxLibIsControllerPresent (StdHeader)) { //VID index = VID index associated with highest SCLK DPM state in the Powerplay state where Label_Performance=1 // This would ignore the UVD case (where Label_Performance would be 0). for (SwSatateIndex = 0 ; SwSatateIndex < PP_FUSE_MAX_NUM_SW_STATE; SwSatateIndex++) { if (PpFuseArray->PolicyLabel[SwSatateIndex] == POLICY_LABEL_PERFORMANCE) { break; } } MaxSclkIndex = 0; CurrentSclkDpmDid = 0xff; ASSERT (PpFuseArray->SclkDpmValid[SwSatateIndex] != 0); for (DpmStateIndex = 0; DpmStateIndex < PP_FUSE_MAX_NUM_DPM_STATE; DpmStateIndex++) { if ((PpFuseArray->SclkDpmValid[SwSatateIndex] & (1 << DpmStateIndex)) != 0) { if (PpFuseArray->SclkDpmDid[DpmStateIndex] < CurrentSclkDpmDid) { CurrentSclkDpmDid = PpFuseArray->SclkDpmDid[DpmStateIndex]; MaxSclkIndex = DpmStateIndex; } } } PpFuseArray->LclkDpmVid[1] = PpFuseArray->SclkDpmVid[MaxSclkIndex]; } else { PpFuseArray->LclkDpmVid[1] = PpFuseArray->LclkDpmVid[0]; PpFuseArray->LclkDpmDid[1] = PpFuseArray->LclkDpmDid[0]; } // - use fused values for LclkDpmDid[0,1,2] and appropriate voltage //Keep using actual fusing IDS_HDT_CONSOLE (NB_MISC, " LCLK DPM use actual fusing.\n"); } //Patch SclkThermDid to 200Mhz if not fused if (PpFuseArray->SclkThermDid == 0) { PpFuseArray->SclkThermDid = GfxLibCalculateDid (200 * 100, GfxLibGetMainPllFreq (StdHeader) * 100); } }
AGESA_STATUS NbInitOnPowerOn ( IN GNB_PLATFORM_CONFIG *Gnb ) { UINTN Index; FCRxFF30_0398_STRUCT FCRxFF30_0398; UINT32 Value; // Init NBCONFIG for (Index = 0; Index < (sizeof (NbPciInitTable) / sizeof (NB_REGISTER_ENTRY)); Index++) { GnbLibPciRMW ( Gnb->GnbPciAddress.AddressValue | NbPciInitTable[Index].Reg, AccessWidth32, NbPciInitTable[Index].Mask, NbPciInitTable[Index].Data, Gnb->StdHeader ); } // Init MISCIND for (Index = 0; Index < (sizeof (NbMiscInitTable) / sizeof (NB_REGISTER_ENTRY)); Index++) { GnbLibPciIndirectRMW ( Gnb->GnbPciAddress.AddressValue | D0F0x60_ADDRESS, NbMiscInitTable[Index].Reg | IOC_WRITE_ENABLE, AccessWidth32, NbMiscInitTable[Index].Mask, NbMiscInitTable[Index].Data, Gnb->StdHeader ); } // Init ORB for (Index = 0; Index < (sizeof (NbOrbInitTable) / sizeof (NB_REGISTER_ENTRY)); Index++) { GnbLibPciIndirectRMW ( Gnb->GnbPciAddress.AddressValue | D0F0x94_ADDRESS, NbOrbInitTable[Index].Reg | (1 << D0F0x94_OrbIndWrEn_OFFSET), AccessWidth32, NbOrbInitTable[Index].Mask, NbOrbInitTable[Index].Data, Gnb->StdHeader ); } if (!GfxLibIsControllerPresent (Gnb->StdHeader)) { FCRxFF30_0398.Value = (1 << FCRxFF30_0398_SoftResetGrbm_OFFSET) | (1 << FCRxFF30_0398_SoftResetMc_OFFSET) | (1 << FCRxFF30_0398_SoftResetDc_OFFSET) | (1 << FCRxFF30_0398_SoftResetRlc_OFFSET) | (1 << FCRxFF30_0398_SoftResetUvd_OFFSET); NbSmuSrbmRegisterWrite (FCRxFF30_0398_ADDRESS, &FCRxFF30_0398.Value, FALSE, Gnb->StdHeader); } Value = 0; for (Index = 0x8400; Index <= 0x85AC; Index = Index + 4) { NbSmuRcuRegisterWrite ( (UINT16) Index, &Value, 1, FALSE, Gnb->StdHeader ); } NbSmuRcuRegisterWrite ( 0x9000, &Value, 1, FALSE, Gnb->StdHeader ); NbSmuRcuRegisterWrite ( 0x9004, &Value, 1, FALSE, Gnb->StdHeader ); return AGESA_SUCCESS; }
AGESA_STATUS GnbMidInterfaceTN ( IN AMD_CONFIG_PARAMS *StdHeader ) { AGESA_STATUS Status; UINT32 Property; AGESA_STATUS AgesaStatus; GNB_HANDLE *GnbHandle; UINT8 SclkDid; AgesaStatus = AGESA_SUCCESS; IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceTN Enter\n"); GnbHandle = GnbGetHandle (StdHeader); ASSERT (GnbHandle != NULL); Property = TABLE_PROPERTY_DEAFULT; Property |= GfxLibIsControllerPresent (StdHeader) ? 0 : TABLE_PROPERTY_IGFX_DISABLED; Property |= GnbBuildOptions.LclkDeepSleepEn ? TABLE_PROPERTY_LCLK_DEEP_SLEEP : 0; Property |= GnbBuildOptions.CfgOrbClockGatingEnable ? TABLE_PROPERTY_ORB_CLK_GATING : 0; Property |= GnbBuildOptions.CfgIocLclkClockGatingEnable ? TABLE_PROPERTY_IOC_LCLK_CLOCK_GATING : 0; Property |= GnbBuildOptions.CfgIocSclkClockGatingEnable ? TABLE_PROPERTY_IOC_SCLK_CLOCK_GATING : 0; Property |= GnbFmCheckIommuPresent (GnbHandle, StdHeader) ? 0: TABLE_PROPERTY_IOMMU_DISABLED; Property |= GnbBuildOptions.SmuSclkClockGatingEnable ? TABLE_PROPERTY_SMU_SCLK_CLOCK_GATING : 0; IDS_OPTION_HOOK (IDS_GNB_PROPERTY, &Property, StdHeader); if ((Property & TABLE_PROPERTY_IOMMU_DISABLED) == 0) { Status = GnbEnableIommuMmioV4 (GnbHandle, StdHeader); AGESA_STATUS_UPDATE (Status, AgesaStatus); Status = GnbIommuMidInit (StdHeader); AGESA_STATUS_UPDATE (Status, AgesaStatus); } // // Set sclk to 100Mhz // SclkDid = GfxRequestSclkTNS3Save ( GfxLibCalculateDidTN (98 * 100, StdHeader), StdHeader ); Status = GnbProcessTable ( GnbHandle, GnbMidInitTableTN, Property, GNB_TABLE_FLAGS_FORCE_S3_SAVE, StdHeader ); AGESA_STATUS_UPDATE (Status, AgesaStatus); // // Restore Sclk // GfxRequestSclkTNS3Save ( SclkDid, StdHeader ); GnbCgttOverrideTN (Property, StdHeader); Status = GnbLclkDpmInitTN (StdHeader); AGESA_STATUS_UPDATE (Status, AgesaStatus); IDS_HDT_CONSOLE (GNB_TRACE, "GnbMidInterfaceTN Exit [0x%x]\n", AgesaStatus); return AgesaStatus; }