| /* $NoKeywords:$ */ |
| /** |
| * @file |
| * |
| * Service procedure to initialize Integrated Info Table |
| * |
| * |
| * |
| * @xrefitem bom "File Content Label" "Release Content" |
| * @e project: AGESA |
| * @e sub-project: GNB |
| * @e \$Revision: 48924 $ @e \$Date: 2011-03-14 12:45:15 -0600 (Mon, 14 Mar 2011) $ |
| * |
| */ |
| /* |
| ***************************************************************************** |
| * |
| * Copyright (c) 2011, Advanced Micro Devices, Inc. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions are met: |
| * * Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * * Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * * Neither the name of Advanced Micro Devices, Inc. nor the names of |
| * its contributors may be used to endorse or promote products derived |
| * from this software without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY |
| * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| * |
| * *************************************************************************** |
| * |
| */ |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * M O D U L E S U S E D |
| *---------------------------------------------------------------------------------------- |
| */ |
| #include "AGESA.h" |
| #include "amdlib.h" |
| #include "Ids.h" |
| #include "heapManager.h" |
| #include "Gnb.h" |
| #include "GnbFuseTable.h" |
| #include "GnbPcie.h" |
| #include "GnbGfx.h" |
| #include GNB_MODULE_DEFINITIONS (GnbCommonLib) |
| #include GNB_MODULE_DEFINITIONS (GnbPcieConfig) |
| #include GNB_MODULE_DEFINITIONS (GnbGfxInitLibV1) |
| #include GNB_MODULE_DEFINITIONS (GnbGfxConfig) |
| #include "GfxLib.h" |
| #include "GfxConfigData.h" |
| #include "GfxRegisterAcc.h" |
| #include "GfxFamilyServices.h" |
| #include "GnbGfxFamServices.h" |
| #include "GfxIntegratedInfoTableInit.h" |
| #include "GnbRegistersON.h" |
| #include "Filecode.h" |
| #define FILECODE PROC_GNB_GFX_GFXINTEGRATEDINFOTABLEINIT_FILECODE |
| /*---------------------------------------------------------------------------------------- |
| * D E F I N I T I O N S A N D M A C R O S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * T Y P E D E F S A N D S T R U C T U R E S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| ULONG ulCSR_M3_ARB_CNTL_DEFAULT[] = { |
| 0x80040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00204080, |
| 0x00204080, |
| 0x0000001E, |
| 0x00000000 |
| }; |
| |
| |
| ULONG ulCSR_M3_ARB_CNTL_UVD[] = { |
| 0x80040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00204080, |
| 0x00204080, |
| 0x0000001E, |
| 0x00000000 |
| }; |
| |
| |
| ULONG ulCSR_M3_ARB_CNTL_FS3D[] = { |
| 0x80040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00040810, |
| 0x00204080, |
| 0x00204080, |
| 0x0000001E, |
| 0x00000000 |
| }; |
| |
| |
| |
| /*---------------------------------------------------------------------------------------- |
| * P R O T O T Y P E S O F L O C A L F U N C T I O N S |
| *---------------------------------------------------------------------------------------- |
| */ |
| |
| UINT32 |
| GfxLibGetCsrPhySrPllPdMode ( |
| IN UINT8 Channel, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| |
| AGESA_STATUS |
| GfxIntegratedInfoTableEntry ( |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| |
| UINT32 |
| GfxLibGetDisDllShutdownSR ( |
| IN UINT8 Channel, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ); |
| |
| VOID |
| GfxIntegratedInfoInitDispclkTable ( |
| IN PP_FUSE_ARRAY *PpFuseArray, |
| IN ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| VOID |
| GfxIntegratedInfoInitSclkTable ( |
| IN PP_FUSE_ARRAY *PpFuseArray, |
| IN ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| VOID |
| GfxFillHtcData ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| VOID |
| GfxFillNbPStateVid ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| VOID |
| GfxFillM3ArbritrationControl ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| |
| VOID |
| GfxFillSbMmioBaseAddress ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| VOID |
| GfxFillNclkInfo ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| AGESA_STATUS |
| GfxIntegratedInfoTableInit ( |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ); |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get CSR phy self refresh power down mode. |
| * |
| * |
| * @param[in] Channel DCT controller index |
| * @param[in] StdHeader Standard configuration header |
| * @retval CsrPhySrPllPdMode |
| */ |
| UINT32 |
| GfxLibGetCsrPhySrPllPdMode ( |
| IN UINT8 Channel, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| D18F2x09C_x0D0FE00A_STRUCT D18F2x09C_x0D0FE00A; |
| |
| GnbLibCpuPciIndirectRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 2, (Channel == 0) ? D18F2x98_ADDRESS : D18F2x198_ADDRESS), |
| D18F2x09C_x0D0FE00A_ADDRESS, |
| &D18F2x09C_x0D0FE00A.Value, |
| StdHeader |
| ); |
| |
| return D18F2x09C_x0D0FE00A.Field.CsrPhySrPllPdMode; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Get disable DLL shutdown in self-refresh mode. |
| * |
| * |
| * @param[in] Channel DCT controller index |
| * @param[in] StdHeader Standard configuration header |
| * @retval DisDllShutdownSR |
| */ |
| UINT32 |
| GfxLibGetDisDllShutdownSR ( |
| IN UINT8 Channel, |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| D18F2x90_STRUCT D18F2x090; |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 2, (Channel == 0) ? D18F2x90_ADDRESS : D18F2x190_ADDRESS), |
| AccessWidth32, |
| &D18F2x090.Value, |
| StdHeader |
| ); |
| |
| return D18F2x090.Field.DisDllShutdownSR; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Build integrated info table |
| * GMC FB access requred |
| * |
| * |
| * @param[in] StdHeader Standard configuration header |
| * @retval AGESA_STATUS |
| */ |
| AGESA_STATUS |
| GfxIntegratedInfoTableEntry ( |
| IN AMD_CONFIG_PARAMS *StdHeader |
| ) |
| { |
| AGESA_STATUS AgesaStatus; |
| AGESA_STATUS Status; |
| GFX_PLATFORM_CONFIG *Gfx; |
| IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableEntry Enter\n"); |
| AgesaStatus = AGESA_SUCCESS; |
| if (GfxLibIsControllerPresent (StdHeader)) { |
| Status = GfxLocateConfigData (StdHeader, &Gfx); |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| if (Status != AGESA_FATAL) { |
| Status = GfxIntegratedInfoTableInit (Gfx); |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| } |
| } |
| IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableEntry Exit[0x%x]\n", AgesaStatus); |
| return AgesaStatus; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Build integrated info table |
| * |
| * |
| * |
| * @param[in] Gfx Gfx configuration info |
| * @retval AGESA_STATUS |
| */ |
| AGESA_STATUS |
| GfxIntegratedInfoTableInit ( |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| AGESA_STATUS Status; |
| AGESA_STATUS AgesaStatus; |
| ATOM_FUSION_SYSTEM_INFO_V1 SystemInfoV1Table; |
| PP_FUSE_ARRAY *PpFuseArray; |
| PCIe_PLATFORM_CONFIG *Pcie; |
| UINT32 IntegratedInfoAddress; |
| ATOM_PPLIB_POWERPLAYTABLE3 *PpTable; |
| UINT8 Channel; |
| |
| AgesaStatus = AGESA_SUCCESS; |
| IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInit Enter\n"); |
| LibAmdMemFill (&SystemInfoV1Table, 0x00, sizeof (ATOM_FUSION_SYSTEM_INFO_V1), GnbLibGetHeader (Gfx)); |
| SystemInfoV1Table.sIntegratedSysInfo.sHeader.usStructureSize = sizeof (ATOM_INTEGRATED_SYSTEM_INFO_V6); |
| ASSERT (SystemInfoV1Table.sIntegratedSysInfo.sHeader.usStructureSize == 512); |
| SystemInfoV1Table.sIntegratedSysInfo.sHeader.ucTableFormatRevision = 1; |
| SystemInfoV1Table.sIntegratedSysInfo.sHeader.ucTableContentRevision = 6; |
| SystemInfoV1Table.sIntegratedSysInfo.ulDentistVCOFreq = GfxLibGetMainPllFreq (GnbLibGetHeader (Gfx)) * 100; |
| SystemInfoV1Table.sIntegratedSysInfo.ulBootUpUMAClock = Gfx->UmaInfo.MemClock * 100; |
| SystemInfoV1Table.sIntegratedSysInfo.usRequestedPWMFreqInHz = Gfx->LcdBackLightControl; |
| SystemInfoV1Table.sIntegratedSysInfo.ucUMAChannelNumber = ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_INTERLEAVE) == 0) ? 1 : 2; |
| SystemInfoV1Table.sIntegratedSysInfo.ucMemoryType = 3; //DDR3 |
| SystemInfoV1Table.sIntegratedSysInfo.ulBootUpEngineClock = 200 * 100; //Set default engine clock to 200MhZ |
| SystemInfoV1Table.sIntegratedSysInfo.usBootUpNBVoltage = GfxLibMaxVidIndex (GnbLibGetHeader (Gfx)); |
| SystemInfoV1Table.sIntegratedSysInfo.ulMinEngineClock = GfxLibGetMinSclk (GnbLibGetHeader (Gfx)); |
| SystemInfoV1Table.sIntegratedSysInfo.usPanelRefreshRateRange = Gfx->DynamicRefreshRate; |
| |
| SystemInfoV1Table.sIntegratedSysInfo.usLvdsSSPercentage = Gfx->LvdsSpreadSpectrum; |
| SystemInfoV1Table.sIntegratedSysInfo.usLvdsSSpreadRateIn10Hz = Gfx->LvdsSpreadSpectrumRate; |
| SystemInfoV1Table.sIntegratedSysInfo.usPCIEClkSSPercentage = Gfx->PcieRefClkSpreadSpectrum; |
| // SystemInfoV1Table.sIntegratedSysInfo.ucLvdsMisc = Gfx->LvdsMiscControl.Value; |
| |
| //Locate PCIe configuration data to get definitions of display connectors |
| SystemInfoV1Table.sIntegratedSysInfo.sExtDispConnInfo.sHeader.usStructureSize = sizeof (ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO); |
| SystemInfoV1Table.sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableFormatRevision = 1; |
| SystemInfoV1Table.sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableContentRevision = 1; |
| SystemInfoV1Table.sIntegratedSysInfo.sExtDispConnInfo.uc3DStereoPinId = Gfx->Gnb3dStereoPinIndex; |
| |
| ASSERT ((Gfx->UmaInfo.UmaAttributes & (UMA_ATTRIBUTE_ON_DCT0 | UMA_ATTRIBUTE_ON_DCT1)) != 0); |
| |
| if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT0) != 0) { |
| Channel = 0; |
| } else { |
| Channel = 1; |
| } |
| if (GfxLibGetCsrPhySrPllPdMode (Channel, GnbLibGetHeader (Gfx)) != 0) { |
| SystemInfoV1Table.sIntegratedSysInfo.ulSystemConfig |= BIT2; |
| } |
| if (GfxLibGetDisDllShutdownSR (Channel, GnbLibGetHeader (Gfx)) == 0) { |
| SystemInfoV1Table.sIntegratedSysInfo.ulSystemConfig |= BIT1; |
| } |
| Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); |
| ASSERT (Status == AGESA_SUCCESS); |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| if (Status == AGESA_SUCCESS) { |
| Status = GfxIntegratedEnumerateAllConnectors ( |
| &SystemInfoV1Table.sIntegratedSysInfo.sExtDispConnInfo.sPath[0], |
| Pcie, |
| Gfx |
| ); |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| } |
| SystemInfoV1Table.sIntegratedSysInfo.usExtDispConnInfoOffset = offsetof (ATOM_INTEGRATED_SYSTEM_INFO_V6, sExtDispConnInfo); |
| // Build PP table |
| PpTable = (ATOM_PPLIB_POWERPLAYTABLE3*) &SystemInfoV1Table.ulPowerplayTable; |
| // Build PP table |
| Status = GfxPowerPlayBuildTable (PpTable, Gfx); |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| // Build info from fuses |
| PpFuseArray = GnbLocateHeapBuffer (AMD_PP_FUSE_TABLE_HANDLE, GnbLibGetHeader (Gfx)); |
| ASSERT (PpFuseArray != NULL); |
| if (PpFuseArray != NULL) { |
| // Build Display clock info |
| GfxIntegratedInfoInitDispclkTable (PpFuseArray, &SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Build Sclk info table |
| GfxIntegratedInfoInitSclkTable (PpFuseArray, &SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| } else { |
| Status = AGESA_ERROR; |
| AGESA_STATUS_UPDATE (Status, AgesaStatus); |
| } |
| // Fill in HTC Data |
| GfxFillHtcData (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Fill in NB P states VID |
| GfxFillNbPStateVid (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Fill in NCLK info |
| GfxFillNclkInfo (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Fill in the M3 arbitration control tables |
| GfxFillM3ArbritrationControl (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Fill South bridge MMIO Base address |
| GfxFillSbMmioBaseAddress (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| // Family specific data update |
| GfxFmIntegratedInfoTableInit (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); |
| IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_INTEGRATED_TABLE_CONFIG, &SystemInfoV1Table.sIntegratedSysInfo, GnbLibGetHeader (Gfx)); |
| //Copy integrated info table to Frame Buffer. (Do not use LibAmdMemCopy, routine not guaranteed access to above 4G memory in 32 bit mode.) |
| IntegratedInfoAddress = (UINT32) (Gfx->UmaInfo.UmaSize - sizeof (ATOM_FUSION_SYSTEM_INFO_V1)); |
| GfxLibCopyMemToFb ((VOID *) (&SystemInfoV1Table), IntegratedInfoAddress, sizeof (ATOM_FUSION_SYSTEM_INFO_V1), Gfx); |
| IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInit Exit [0x%x]\n", Status); |
| return Status; |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init Dispclk <-> VID table |
| * |
| * |
| * @param[in] PpFuseArray Fuse array pointer |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxIntegratedInfoInitDispclkTable ( |
| IN PP_FUSE_ARRAY *PpFuseArray, |
| IN ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| UINTN Index; |
| for (Index = 0; Index < 4; Index++) { |
| if (PpFuseArray->DisplclkDid[Index] != 0) { |
| IntegratedInfoTable->sDISPCLK_Voltage[Index].ulMaximumSupportedCLK = GfxLibCalculateClk ( |
| PpFuseArray->DisplclkDid[Index], |
| IntegratedInfoTable->ulDentistVCOFreq |
| ); |
| IntegratedInfoTable->sDISPCLK_Voltage[Index].ulVoltageIndex = (ULONG) Index; |
| } |
| } |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init Sclk <-> VID table |
| * |
| * |
| * @param[in] PpFuseArray Fuse array pointer |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxIntegratedInfoInitSclkTable ( |
| IN PP_FUSE_ARRAY *PpFuseArray, |
| IN ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| UINTN Index; |
| UINTN TargetIndex; |
| UINTN ValidSclkStateMask; |
| UINT8 TempDID; |
| UINT8 SclkVidArray[4]; |
| UINTN AvailSclkIndex; |
| ATOM_AVAILABLE_SCLK_LIST *AvailSclkList; |
| BOOLEAN Sorting; |
| AvailSclkList = &IntegratedInfoTable->sAvail_SCLK[0]; |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x15C_ADDRESS), |
| AccessWidth32, |
| &SclkVidArray[0], |
| GnbLibGetHeader (Gfx) |
| ); |
| AvailSclkIndex = 0; |
| for (Index = 0; Index < MAX_NUM_OF_FUSED_DPM_STATES; Index++) { |
| if (PpFuseArray->SclkDpmDid[Index] != 0) { |
| AvailSclkList[AvailSclkIndex].ulSupportedSCLK = GfxLibCalculateClk (PpFuseArray->SclkDpmDid[Index], IntegratedInfoTable->ulDentistVCOFreq); |
| AvailSclkList[AvailSclkIndex].usVoltageIndex = PpFuseArray->SclkDpmVid[Index]; |
| AvailSclkList[AvailSclkIndex].usVoltageID = SclkVidArray [PpFuseArray->SclkDpmVid[Index]]; |
| AvailSclkIndex++; |
| } |
| } |
| //Sort by VoltageIndex & ulSupportedSCLK |
| do { |
| Sorting = FALSE; |
| for (Index = 0; Index < (AvailSclkIndex - 1); Index++) { |
| ATOM_AVAILABLE_SCLK_LIST Temp; |
| BOOLEAN Exchange; |
| Exchange = FALSE; |
| if (AvailSclkList[Index].usVoltageIndex > AvailSclkList[Index + 1].usVoltageIndex) { |
| Exchange = TRUE; |
| } |
| if ((AvailSclkList[Index].usVoltageIndex == AvailSclkList[Index + 1].usVoltageIndex) && |
| (AvailSclkList[Index].ulSupportedSCLK > AvailSclkList[Index + 1].ulSupportedSCLK)) { |
| Exchange = TRUE; |
| } |
| if (Exchange) { |
| Sorting = TRUE; |
| LibAmdMemCopy (&Temp, &AvailSclkList[Index], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx)); |
| LibAmdMemCopy (&AvailSclkList[Index], &AvailSclkList[Index + 1], sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx)); |
| LibAmdMemCopy (&AvailSclkList[Index + 1], &Temp, sizeof (ATOM_AVAILABLE_SCLK_LIST), GnbLibGetHeader (Gfx)); |
| } |
| } |
| } while (Sorting); |
| |
| if (PpFuseArray->GpuBoostCap == 1) { |
| IntegratedInfoTable->SclkDpmThrottleMargin = PpFuseArray->SclkDpmThrottleMargin; |
| IntegratedInfoTable->SclkDpmTdpLimitPG = PpFuseArray->SclkDpmTdpLimitPG; |
| IntegratedInfoTable->EnableBoost = PpFuseArray->GpuBoostCap; |
| IntegratedInfoTable->SclkDpmBoostMargin = PpFuseArray->SclkDpmBoostMargin; |
| IntegratedInfoTable->SclkDpmTdpLimitBoost = (PpFuseArray->SclkDpmTdpLimit)[5]; |
| IntegratedInfoTable->ulBoostEngineCLock = GfxFmCalculateClock ((PpFuseArray->SclkDpmDid)[5], GnbLibGetHeader (Gfx)); |
| IntegratedInfoTable->ulBoostVid_2bit = (PpFuseArray->SclkDpmVid)[5]; |
| |
| ValidSclkStateMask = 0; |
| TargetIndex = 0; |
| for (Index = 0; Index < 6; Index++) { |
| ValidSclkStateMask |= (PpFuseArray->SclkDpmValid)[Index]; |
| } |
| TempDID = 0x7F; |
| for (Index = 0; Index < 6; Index++) { |
| if ((ValidSclkStateMask & ((UINTN)1 << Index)) != 0) { |
| if ((PpFuseArray->SclkDpmDid)[Index] <= TempDID) { |
| TempDID = (PpFuseArray->SclkDpmDid)[Index]; |
| TargetIndex = Index; |
| } |
| } |
| } |
| IntegratedInfoTable->GnbTdpLimit = (PpFuseArray->SclkDpmTdpLimit)[TargetIndex]; |
| } |
| |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init HTC Data |
| * |
| * |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxFillHtcData ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| D18F3x64_STRUCT D18F3x64; |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3x64_ADDRESS), |
| AccessWidth32, |
| &D18F3x64.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| IntegratedInfoTable->ucHtcTmpLmt = (UCHAR) (D18F3x64.Field.HtcTmpLmt / 2 + 52); |
| IntegratedInfoTable->ucHtcHystLmt = (UCHAR) (D18F3x64.Field.HtcHystLmt / 2); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init NbPstateVid |
| * |
| * |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxFillNbPStateVid ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| D18F3xDC_STRUCT D18F3xDC; |
| D18F6x90_STRUCT D18F6x90; |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3xDC_ADDRESS), |
| AccessWidth32, |
| &D18F3xDC.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| IntegratedInfoTable->usNBP0Voltage = (USHORT) D18F3xDC.Field.NbPs0Vid; |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 6, D18F6x90_ADDRESS), |
| AccessWidth32, |
| &D18F6x90.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| IntegratedInfoTable->usNBP1Voltage = (USHORT) D18F6x90.Field.NbPs1Vid; |
| IntegratedInfoTable->ulMinimumNClk = GfxLibCalculateClk ( |
| (UINT8) (((D18F6x90.Field.NbPs1NclkDiv != 0) && (D18F6x90.Field.NbPs1NclkDiv < D18F3xDC.Field.NbPs0NclkDiv)) ? D18F6x90.Field.NbPs1NclkDiv : D18F3xDC.Field.NbPs0NclkDiv), |
| IntegratedInfoTable->ulDentistVCOFreq |
| ); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init M3 Arbitration Control values. |
| * |
| * |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxFillM3ArbritrationControl ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| LibAmdMemCopy (IntegratedInfoTable->ulCSR_M3_ARB_CNTL_DEFAULT, ulCSR_M3_ARB_CNTL_DEFAULT, sizeof (ulCSR_M3_ARB_CNTL_DEFAULT), GnbLibGetHeader (Gfx)); |
| LibAmdMemCopy (IntegratedInfoTable->ulCSR_M3_ARB_CNTL_UVD, ulCSR_M3_ARB_CNTL_UVD, sizeof (ulCSR_M3_ARB_CNTL_UVD), GnbLibGetHeader (Gfx)); |
| LibAmdMemCopy (IntegratedInfoTable->ulCSR_M3_ARB_CNTL_FS3D, ulCSR_M3_ARB_CNTL_FS3D, sizeof (ulCSR_M3_ARB_CNTL_FS3D), GnbLibGetHeader (Gfx)); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| *Init M3 Arbitration Control values. |
| * |
| * |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxFillSbMmioBaseAddress ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| UINT8 Index; |
| UINT32 SbMmioBaseAddress; |
| SbMmioBaseAddress = 0; |
| //Read Dword from PMIO 24h. SB PMIO region supports only byte read. |
| for (Index = 0x24; Index < 0x28; Index++) { |
| GnbLibIoWrite (SB_IOMAP_REGCD6, AccessWidth8, &Index, GnbLibGetHeader (Gfx)); |
| GnbLibIoRead (SB_IOMAP_REGCD7, AccessWidth8, &(((UINT8*) &SbMmioBaseAddress)[Index - 0x24]), GnbLibGetHeader (Gfx)); |
| } |
| // If MMIO is enabled and set for memory(not IO) then set MMIO_Base_Addr parameter. |
| if ((SbMmioBaseAddress & (SB_MMIO_IO_MAPPED_ENABLE | SB_MMIO_DECODE_ENABLE)) == SB_MMIO_DECODE_ENABLE) { |
| IntegratedInfoTable->ulSB_MMIO_Base_Addr = (ULONG) (SbMmioBaseAddress & (~SB_MMIO_DECODE_ENABLE)) ; |
| } else { |
| IntegratedInfoTable->ulSB_MMIO_Base_Addr = 0; |
| } |
| IDS_HDT_CONSOLE (GFX_MISC, " ulSB_MMIO_Base_Addr = 0x%x\n", IntegratedInfoTable->ulSB_MMIO_Base_Addr); |
| } |
| |
| /*----------------------------------------------------------------------------------------*/ |
| /** |
| * Fill in NCLK info |
| * |
| * set ulMinimumNClk and ulIdleNClk |
| * |
| * @param[in] IntegratedInfoTable Integrated info table pointer |
| * @param[in] Gfx Gfx configuration info |
| */ |
| |
| VOID |
| GfxFillNclkInfo ( |
| IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V6 *IntegratedInfoTable, |
| IN GFX_PLATFORM_CONFIG *Gfx |
| ) |
| { |
| |
| D18F3xA0_STRUCT D18F3xA0; |
| D18F6x9C_STRUCT D18F6x9C; |
| D18F3xDC_STRUCT D18F3xDC; |
| D18F6x90_STRUCT D18F6x90; |
| |
| // |
| // ulIdleNClk = GfxLibGetMainPllFreq (...) / F6x9C[NclkRedDiv] divisor (main PLL frequency / NCLK divisor) |
| // |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 6, D18F6x9C_ADDRESS), |
| AccessWidth32, |
| &D18F6x9C.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| |
| IntegratedInfoTable->ulIdleNClk = GfxLibCalculateIdleNclk ( |
| (UINT8) D18F6x9C.Field.NclkRedDiv, |
| IntegratedInfoTable->ulDentistVCOFreq |
| ); |
| |
| // |
| // Set ulMinimumNClk depends on CPU fused and NB Pstate. |
| // |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3xA0_ADDRESS), |
| AccessWidth32, |
| &D18F3xA0.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| |
| if (D18F3xA0.Field.CofVidProg) { |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 3, D18F3xDC_ADDRESS), |
| AccessWidth32, |
| &D18F3xDC.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| |
| GnbLibPciRead ( |
| MAKE_SBDFO ( 0, 0, 0x18, 6, D18F6x90_ADDRESS), |
| AccessWidth32, |
| &D18F6x90.Value, |
| GnbLibGetHeader (Gfx) |
| ); |
| |
| // |
| // Set ulMinimumNClk if (F6x90[NbPsCap]==1 && F6x90[NbPsCtrlDis]==0) then ( |
| // GfxLibGetMainPllFreq (...) / F6x90[NbPs1NclkDiv] divisor |
| // ) else ( GfxLibGetMainPllFreq (...) / F3xDC[NbPs0NclkDiv] divisor |
| // ) |
| // |
| IntegratedInfoTable->ulMinimumNClk = GfxLibCalculateNclk ( |
| (UINT8) (((D18F6x90.Field.NbPsCap == 1) && (D18F6x90.Field.NbPsCtrlDis == 0)) ? D18F6x90.Field.NbPs1NclkDiv : D18F3xDC.Field.NbPs0NclkDiv), |
| IntegratedInfoTable->ulDentistVCOFreq |
| ); |
| } else { |
| IntegratedInfoTable->ulMinimumNClk = 200 * 100; |
| } |
| |
| } |