diff options
author | Siyuan Wang <wangsiyuanbuaa@gmail.com> | 2013-07-25 15:14:15 +0800 |
---|---|---|
committer | Bruce Griffith <Bruce.Griffith@se-eng.com> | 2013-08-04 05:40:37 +0200 |
commit | affe85fbc8a13d35960aa92ae87cbb6330ad253f (patch) | |
tree | 9c1ace69f12b06b6544faf041994aa4288fb2e45 /src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3 | |
parent | ae8d06969bdde9b1250bc3c4ad93f5db408dae98 (diff) |
AMD Kabini: Add AGESA/PI code for new processor family
Change-Id: Icb6f64e2e3cfd678fb4fb4f13f0e4b678d5acc4a
Signed-off-by: Siyuan Wang <SiYuan.Wang@amd.com>
Signed-off-by: Siyuan Wang <wangsiyuanbuaa@gmail.com>
Reviewed-by: Nick Dill <nick.dill@se-eng.com>
Tested-by: Bruce Griffith <bruce.griffith@se-eng.com>
Reviewed-on: http://review.coreboot.org/3836
Tested-by: build bot (Jenkins)
Reviewed-by: Martin Roth <martin.roth@se-eng.com>
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3')
6 files changed, 2458 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c new file mode 100644 index 0000000000..7b5f3ef9de --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c @@ -0,0 +1,504 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Integrated table info init + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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 "GeneralServices.h" +#include "Gnb.h" +#include "GnbF1Table.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbSbLib.h" +#include "GnbCommonLib.h" +#include "GnbPcieConfig.h" +#include "GnbGfxConfig.h" +#include "GnbGfxInitLibV1.h" +#include "GnbGfxFamServices.h" +#include "GnbNbInitLibV1.h" +#include "GnbNbInitLibV5.h" +#include "GfxConfigLib.h" +#include "GfxIntegratedInfoTable.h" +#include "GfxPwrPlayTable.h" +#include "OptionGnb.h" +#include "GfxLibV3.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXINTEGRATEDINFOTABLE_FILECODE +/*---------------------------------------------------------------------------------------- + * D E F I N I T I O N S A N D M A C R O S + *---------------------------------------------------------------------------------------- + */ +extern GNB_BUILD_OPTIONS GnbBuildOptions; + +/*---------------------------------------------------------------------------------------- + * T Y P E D E F S A N D S T R U C T U R E S + *---------------------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Init V3 Support for eDP to Lvds translators + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntegrateducEDPToLVDSRxIdCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *uceDPToLVDSRxId; + uceDPToLVDSRxId = (UINT8*) Buffer; + // APU output DP signal to a 3rd party DP translator chip (Analogix, Parade etc), + // the chip is handled by the 3rd party DP Rx firmware and it does not require the AMD SW to have a special + // initialize/enable/disable sequence to control this chip, the AMD SW just follows the eDP spec + // to enable the LVDS panel through this chip. + + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvds) { + *uceDPToLVDSRxId = eDP_TO_LVDS_COMMON_ID; + IDS_HDT_CONSOLE (GNB_TRACE, "Found 3rd party common EDPToLvds Connector\n"); + } + // APU output DP signal to a 3rd party DP translator chip which requires a AMD SW one time initialization + // to the chip based on the LVDS panel parameters ( such as power sequence time and panel SS parameter etc ). + // After that, the AMD SW does not need any specific enable/disable sequences to control this chip and just + // follows the eDP spec. to control the panel. + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeEDPToLvdsSwInit) { + *uceDPToLVDSRxId = eDP_TO_LVDS_SWINIT_ID; + IDS_HDT_CONSOLE (GNB_TRACE, "Found EDPToLvds Connector requiring SW init\n"); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Calculate V3 NCLK clock + * + * + * + * @param[in] NbFid NbFid + * @param[in] NbDid NbDid + * @retval Clock in 10KHz + */ + +STATIC UINT32 +GfxLibGetNclkV3 ( + IN UINT8 NbFid, + IN UINT8 NbDid + ) +{ + UINT32 Divider; + //i.e. NBCOF[0] = (100 * ([NbFid] + 4h) / (2^[NbDid])) Mhz + if (NbDid == 1) { + Divider = 2; + } else if (NbDid == 0) { + Divider = 1; + } else { + Divider = 1; + } + ASSERT (NbDid == 0 || NbDid == 1); + return ((10000 * (NbFid + 4)) / Divider); +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init V3 Nb p-State MemclkFreq + * + * + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] PpF1Array pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillNbPstateMemclkFreqV3 ( + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN PP_F1_ARRAY_V2 *PpF1Array, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 i; + UINT8 Channel; + ULONG memps0_freq; + ULONG memps1_freq; + + Channel = 0; + if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT1) != 0) { + Channel = 1; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT2) != 0) { + Channel = 2; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT3) != 0) { + Channel = 3; + } + + + memps0_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) PpF1Array->MemClkFreq[Channel], GnbLibGetHeader (Gfx)); + memps1_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) PpF1Array->M1MemClkFreq[Channel], GnbLibGetHeader (Gfx)); + + for (i = 0; i < 4; i++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld26[i] == 1) { + IntegratedInfoTable->ulNbpStateMemclkFreq[i] = (PpF1Array->PP_FUSE_ARRAY_V2_fld29[i] == 0) ? memps0_freq : memps1_freq; + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + *Init V3 NbPstateVid + * + * + * @param[in] PpF1Array + * @param[in] IntegratedInfoTable Integrated info table pointer + * @param[in] Gfx Gfx configuration info + */ + +STATIC VOID +GfxFillNbPStateVidV3 ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 i; + + for (i = 0; i < 4; i++) { + IntegratedInfoTable->usNBPStateVoltage[i] = (USHORT) ((PpF1Array->PP_FUSE_ARRAY_V2_fld28[i] << 7) | (PpF1Array->PP_FUSE_ARRAY_V2_fld27[i])); + IntegratedInfoTable->ulNbpStateNClkFreq[i] = GfxLibGetNclkV3 ((UINT8) (PpF1Array->PP_FUSE_ARRAY_V2_fld30[i]), (UINT8) (PpF1Array->PP_FUSE_ARRAY_V2_fld31[i])); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy memory content to FB + * + * + * @param[in] SystemInfoTableV3Ptr Pointer to integrated info table + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxIntInfoTablePostToFbV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 Index; + UINT32 TableOffset; + UINT32 FbAddress; + TableOffset = (UINT32) (Gfx->UmaInfo.UmaSize - sizeof (ATOM_FUSION_SYSTEM_INFO_V3)) | 0x80000000; + for (Index = 0; Index < sizeof (ATOM_FUSION_SYSTEM_INFO_V3); Index = Index + 4 ) { + FbAddress = TableOffset + Index; + GnbLibMemWrite (Gfx->GmmBase + GMMx00_ADDRESS, AccessWidth32, &FbAddress, GnbLibGetHeader (Gfx)); + GnbLibMemWrite (Gfx->GmmBase + GMMx04_ADDRESS, AccessWidth32, (UINT8*) SystemInfoTableV3Ptr + Index, GnbLibGetHeader (Gfx)); + } +} + + +STATIC VOID +GfxIntegratedInfoTable289_fun ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINTN Index; + for (Index = 0; Index < 4; Index++) { + if (PpF1Array->excel841_fld6[Index] != 0) { + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulMaximumSupportedCLK = GfxFmCalculateClock ( + PpF1Array->excel841_fld6[Index], + GnbLibGetHeader (Gfx) + ); + IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld4[Index].ulVoltageIndex = (ULONG) Index; + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxIntegratedInfoTable318_fun ( + IN PP_F1_ARRAY_V2 *PpF1Array, + IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT8 Index; + UINTN v1; + GnbGfx275_STRUCT *pv2; + BOOLEAN Sorting; + pv2 = &IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8[0]; + + v1 = 0; + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index] != 0) { + pv2[v1].GnbGfx275_STRUCT_fld0 = GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index], GnbLibGetHeader (Gfx)); + pv2[v1].GnbGfx275_STRUCT_fld1 = Index; + pv2[v1].GnbGfx275_STRUCT_fld2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; + v1++; + } + } + if (v1 > 1) { + do { + Sorting = FALSE; + for (Index = 0; Index < (v1 - 1); Index++) { + GnbGfx275_STRUCT Temp; + BOOLEAN Exchange; + Exchange = FALSE; + if (pv2[Index].GnbGfx275_STRUCT_fld1 > pv2[Index + 1].GnbGfx275_STRUCT_fld1) { + Exchange = TRUE; + } + if ((pv2[Index].GnbGfx275_STRUCT_fld1 == pv2[Index + 1].GnbGfx275_STRUCT_fld1) && + (pv2[Index].GnbGfx275_STRUCT_fld0 > pv2[Index + 1].GnbGfx275_STRUCT_fld0)) { + Exchange = TRUE; + } + if (Exchange) { + Sorting = TRUE; + LibAmdMemCopy (&Temp, &pv2[Index], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&pv2[Index], &pv2[Index + 1], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + LibAmdMemCopy (&pv2[Index + 1], &Temp, sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx)); + } + } + } while (Sorting); + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build integrated info table + * + * + * + * @param[in] Gfx Gfx configuration info + * @param[in] SystemInfoTableV3 ATOM_FUSION_SYSTEM_INFO_V3 pointer + * @param[in] PpF1Array + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxIntInfoTableInitV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3, + IN PP_F1_ARRAY_V2 *PpF1Array + ) +{ + AGESA_STATUS Status; + AGESA_STATUS AgesaStatus; + PCIe_PLATFORM_CONFIG *Pcie; + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + UINT8 Channel; + + AgesaStatus = AGESA_SUCCESS; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInitV3 Enter\n"); + + if (PpF1Array != NULL) { + + Channel = 0; + if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT1) != 0) { + Channel = 1; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT2) != 0) { + Channel = 2; + } else if ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_ON_DCT3) != 0) { + Channel = 3; + } + SystemInfoTableV3->sIntegratedSysInfo.sHeader.usStructureSize = sizeof (ATOM_INTEGRATED_SYSTEM_INFO_V1_8); + ASSERT (SystemInfoTableV3->sIntegratedSysInfo.sHeader.usStructureSize == 512); + SystemInfoTableV3->sIntegratedSysInfo.sHeader.ucTableFormatRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sHeader.ucTableContentRevision = 8; + SystemInfoTableV3->sIntegratedSysInfo.ulBootUpEngineClock = 200 * 100; //Set default engine clock to 200MhZ + SystemInfoTableV3->sIntegratedSysInfo.field2 = (PpF1Array->PP_FUSE_ARRAY_V2_fld21 + 0x10) * 10000; + SystemInfoTableV3->sIntegratedSysInfo.ulBootUpUMAClock = Gfx->UmaInfo.MemClock * 100; + + SystemInfoTableV3->sIntegratedSysInfo.usRequestedPWMFreqInHz = Gfx->LcdBackLightControl; + SystemInfoTableV3->sIntegratedSysInfo.ucUMAChannelNumber = ((Gfx->UmaInfo.UmaAttributes & UMA_ATTRIBUTE_INTERLEAVE) == 0) ? 1 : 2; + SystemInfoTableV3->sIntegratedSysInfo.ucMemoryType = Gfx->UmaInfo.MemType; + SystemInfoTableV3->sIntegratedSysInfo.usBootUpNBVoltage = GnbLocateHighestVidIndexV5 (GnbLibGetHeader (Gfx)); + SystemInfoTableV3->sIntegratedSysInfo.usPanelRefreshRateRange = Gfx->DynamicRefreshRate; + SystemInfoTableV3->sIntegratedSysInfo.usLvdsSSPercentage = Gfx->LvdsSpreadSpectrum; + //Locate PCIe configuration data to get definitions of display connectors + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.usStructureSize = sizeof (ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO); + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableFormatRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sHeader.ucTableContentRevision = 1; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uc3DStereoPinId = Gfx->Gnb3dStereoPinIndex; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.ucRemoteDisplayConfig = Gfx->GnbRemoteDisplaySupport; + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.ucFixDPVoltageSwing = (UINT8) Gfx->DpFixedVoltSwingType; + SystemInfoTableV3->sIntegratedSysInfo.usExtDispConnInfoOffset = offsetof (ATOM_INTEGRATED_SYSTEM_INFO_V1_8, sExtDispConnInfo); + + SystemInfoTableV3->sIntegratedSysInfo.usPCIEClkSSPercentage = Gfx->PcieRefClkSpreadSpectrum; + + SystemInfoTableV3->sIntegratedSysInfo.ucLvdsMisc = Gfx->LvdsMiscControl.Value; + IDS_HDT_CONSOLE (GNB_TRACE, "Lvds Misc control : %x\n", Gfx->LvdsMiscControl.Value); + if (Gfx->LvdsMiscControl.Field.LvdsVoltOverwriteEn) { + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSVoltAdjust = Gfx->LVDSVoltAdjust; + IDS_HDT_CONSOLE (GNB_TRACE, "LVDSVoltAdjust : %x\n", Gfx->LVDSVoltAdjust); + } + + SystemInfoTableV3->sIntegratedSysInfo.ulVBIOSMisc = Gfx->DisplayMiscControl.Value; + IDS_HDT_CONSOLE (GNB_TRACE, "Display Misc control : %x\n", Gfx->DisplayMiscControl.Value); + + // LVDS + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqDIGONtoDE_in4Ms = Gfx->LvdsPowerOnSeqDigonToDe; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqDEtoVARY_BL_in4Ms = Gfx->LvdsPowerOnSeqDeToVaryBl; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqVARY_BLtoDE_in4Ms = Gfx->LvdsPowerOnSeqVaryBlToDe; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqDEtoDIGON_in4Ms = Gfx->LvdsPowerOnSeqDeToDigon; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSOffToOnDelay_in4Ms = Gfx->LvdsPowerOnSeqOnToOffDelay; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOnSeqVARY_BLtoBLON_in4Ms = Gfx->LvdsPowerOnSeqVaryBlToBlon; + SystemInfoTableV3->sIntegratedSysInfo.ucLVDSPwrOffSeqBLONtoVARY_BL_in4Ms = Gfx->LvdsPowerOnSeqBlonToVaryBl; + SystemInfoTableV3->sIntegratedSysInfo.ulLCDBitDepthControlVal = Gfx->LcdBitDepthControlValue; + SystemInfoTableV3->sIntegratedSysInfo.usMaxLVDSPclkFreqInSingleLink = Gfx->LvdsMaxPixelClockFreq; + SystemInfoTableV3->sIntegratedSysInfo.ucMinAllowedBL_Level = Gfx->MinAllowedBLLevel; + Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); + ASSERT (Status == AGESA_SUCCESS); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + if (Status == AGESA_SUCCESS) { + Status = GfxIntegratedEnumerateAllConnectors ( + &SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.sPath[0], + Pcie, + Gfx + ); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uceDPToLVDSRxId = eDP_TO_LVDS_RX_DISABLE; + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_VIRTUAL | DESCRIPTOR_DDI_ENGINE, + GfxIntegrateducEDPToLVDSRxIdCallback, + &SystemInfoTableV3->sIntegratedSysInfo.sExtDispConnInfo.uceDPToLVDSRxId, + Pcie + ); + + // Build PP table + PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3->ulPowerplayTable; + // Build PP table + ///@todo + //Status = GfxPowerPlayBuildTable (PpTable, Gfx); + AGESA_STATUS_UPDATE (Status, AgesaStatus); + // Assign usFormatID to 0x000B to represent V3 + ///@todo + PpTable->usFormatID = 0xB; + // Build Display clock info + GfxIntegratedInfoTable289_fun (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + GfxIntegratedInfoTable318_fun (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + ///@todo review if these parameters needed + // Fill in Nb P-state MemclkFreq Data + GfxFillNbPstateMemclkFreqV3 (&SystemInfoTableV3->sIntegratedSysInfo, PpF1Array, Gfx); + // Fill in HTC Data + if (PpF1Array->HtcEn == 1) { + SystemInfoTableV3->sIntegratedSysInfo.ucHtcTmpLmt = (UCHAR) (PpF1Array->HtcTmpLmt / 2 + 52); + SystemInfoTableV3->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = (UCHAR) (PpF1Array->PP_FUSE_ARRAY_V2_fld20 / 2); + } else { + SystemInfoTableV3->sIntegratedSysInfo.ucHtcTmpLmt = 0; + SystemInfoTableV3->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = 0; + } + // Fill in NB P states VID & NCLK info + GfxFillNbPStateVidV3 (PpF1Array, &SystemInfoTableV3->sIntegratedSysInfo, Gfx); + + // Family specific data update - store default values to be updated by family specific code + //GfxFmIntegratedInfoTableInit (&SystemInfoV1Table.sIntegratedSysInfo, Gfx); + SystemInfoTableV3->sIntegratedSysInfo.ulDDR_DLL_PowerUpTime = 4940; + SystemInfoTableV3->sIntegratedSysInfo.ulDDR_PLL_PowerUpTime = 2000; + + if (PpF1Array->MemPhyPllPdMode[Channel] != 0) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT2; + } + if (PpF1Array->DisDllShutdownSR[Channel] == 0) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT1; + } + if (GnbBuildOptions.CfgPciePowerGatingFlags != (PCIE_POWERGATING_SKIP_CORE | PCIE_POWERGATING_SKIP_PHY)) { + SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig |= BIT0; + } + SystemInfoTableV3->sIntegratedSysInfo.ulGPUCapInfo = GPUCAPINFO_TMDS_HDMI_USE_CASCADE_PLL_MODE | GPUCAPINFO_DP_USE_SINGLE_PLL_MODE; + + IDS_HDT_CONSOLE (GNB_TRACE, "ulSystemConfig : %x\n", SystemInfoTableV3->sIntegratedSysInfo.ulSystemConfig); + + } else { + Status = AGESA_ERROR; + AGESA_STATUS_UPDATE (Status, AgesaStatus); + } + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntegratedInfoTableInitV3 Exit [0x%x]\n", Status); + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump gfx integrated info table + * + * + * @param[in] SystemInfoTableV3Ptr Pointer to integrated info table + * @param[in] Gfx Pointer to global GFX configuration + * + */ +VOID +GfxIntInfoTableDebugDumpV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + + IDS_HDT_CONSOLE (GFX_MISC, "GfxIntInfoTableDebugDumpV3 Enter\n"); + + PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3Ptr->ulPowerplayTable; + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) ((UINT8 *) (PpTable) + PpTable->usExtendendedHeaderOffset); + IDS_HDT_CONSOLE (GFX_MISC, " ExtendedHeader usSize %d\n", ExtendedHeader->usSize); + IDS_HDT_CONSOLE (GFX_MISC, " SizeOf %d\n", sizeof(ATOM_PPLIB_EXTENDEDHEADER)); + + IDS_HDT_CONSOLE (GFX_MISC, " ucHtcTmpLmt 0x%X\n", SystemInfoTableV3Ptr->sIntegratedSysInfo.ucHtcTmpLmt); + IDS_HDT_CONSOLE (GFX_MISC, " ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 0x%X\n", SystemInfoTableV3Ptr->sIntegratedSysInfo.ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11); + IDS_HDT_CONSOLE (GFX_MISC, "GfxIntInfoTableDebugDumpV3 Exit\n"); +} + diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h new file mode 100644 index 0000000000..562f815ea2 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h @@ -0,0 +1,73 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various GfxIntegratedInfoTable definitions + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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. +* *************************************************************************** +* +*/ +#ifndef _GFXINTEGRATEDINFOTABLE_H_ +#define _GFXINTEGRATEDINFOTABLE_H_ + +AGESA_STATUS +GfxIntInfoTableInitV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3, + IN PP_F1_ARRAY_V2 *PpF1Array + ); + +VOID +GfxIntInfoTablePostToFbV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +VOID +GfxIntInfoTableDebugDumpV3 ( + IN ATOM_FUSION_SYSTEM_INFO_V3 *SystemInfoTableV3Ptr, + IN GFX_PLATFORM_CONFIG *Gfx + ); + +// GMMx00/x04 are required for copying table to frame buffer +#ifndef GMMx00_ADDRESS + #define GMMx00_ADDRESS 0x0 + #define GMMx04_ADDRESS 0x4 +#endif + +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c new file mode 100644 index 0000000000..1ad00c9c5f --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c @@ -0,0 +1,257 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Family specific GFX library + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 85947 $ @e \$Date: 2013-01-14 17:25:21 -0600 (Mon, 14 Jan 2013) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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 "S3SaveState.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbGfx.h" +#include "GfxLibV3.h" +#include "GnbSmuInitLibV7.h" +#include "GnbCommonLib.h" +#include "GnbRegistersCommonV2.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXLIBV3_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 + *---------------------------------------------------------------------------------------- + */ +CONST UINT16 GfxMemClockFrequencyDefinitionTableV3 [][8] = { +{0, 0, 0, 0, 333, 0, 400, 0}, +{0, 0, 533, 0, 0, 0, 667, 0}, +{0, 0, 800, 0, 0, 0, 933, 0}, +{0, 1050, 1066, 0, 0, 0, 0, 0} +}; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +/*----------------------------------------------------------------------------------------*/ +/** + * Extract DRAM frequency + * + * + * + * @param[in] Encoding Memory Clock Frequency Value Definition + * @param[in] StdHeader Standard configuration header + * @retval Dram frequency Mhz + */ +UINT32 +GfxLibExtractDramFrequencyV3 ( + IN UINT8 Encoding, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + if (Encoding >= (sizeof (GfxMemClockFrequencyDefinitionTableV3) / sizeof (UINT16))) { + ASSERT (FALSE); + return 0; + } + return GfxMemClockFrequencyDefinitionTableV3[Encoding / 8][Encoding % 8]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enable GMM Access for gBIF BAR Arrangement + * + * + * + * @param[in,out] Gfx Pointer to GFX configuration + * @retval AGESA_STATUS + */ + +AGESA_STATUS +GfxEnableGmmAccessV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINT32 Value; + + if (!GnbLibPciIsDevicePresent (Gfx->GfxPciAddress.AddressValue, GnbLibGetHeader (Gfx))) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for GMM allocated by reading D1F0x24 Graphics Memory Mapped Base Address + Gfx->GmmBase = 0; + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x24, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + Gfx->GmmBase |= (Value & 0xfffffff0); + if (Gfx->GmmBase == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + + // Check if base address for FB allocated + GnbLibPciRead (Gfx->GfxPciAddress.AddressValue | 0x10, AccessWidth32, &Value, GnbLibGetHeader (Gfx)); + if ((Value & 0xfffffff0) == 0) { + IDS_ERROR_TRAP; + return AGESA_ERROR; + } + //Push CPU MMIO pci config to S3 script + GnbLibS3SaveConfigSpace (MAKE_SBDFO (0, 0, 0x18, 1, 0), 0xBC, 0x80, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + // Turn on memory decoding on GFX to enable access to GMM register space + GnbLibPciRMW (Gfx->GfxPciAddress.AddressValue | 0x4, AccessWidth32, 0xffffffff, BIT1 | BIT2, GnbLibGetHeader (Gfx)); + //Push iGPU pci config to S3 script + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x24, 0x10, AccessS3SaveWidth32, GnbLibGetHeader (Gfx)); + GnbLibS3SaveConfigSpace (Gfx->GfxPciAddress.AddressValue, 0x04, 0x04, AccessS3SaveWidth16, GnbLibGetHeader (Gfx)); + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Power Up/Down iGPU + * + * + * + * @param[in,out] Gfx Pointer to GFX configuration + * @param[in,out] PowerControl Control power Up/Down iGPU, 0, power down iGPU, 1, power on iGPU + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxRequestGPUPowerV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx, + IN UINT8 PowerControl + ) +{ + GNB_HANDLE *GnbHandle; + DEV_OBJECT DevObject; + + GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx)); + DevObject.DevPciAddress.AddressValue = MAKE_SBDFO (0, 0, 0, 0, 0); + DevObject.GnbHandle = GnbHandle; + DevObject.StdHeader = GnbLibGetHeader (Gfx); + + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Determine number of audio ports for each connector + * + * + * + * @param[in] Engine Engine configuration info + * @param[in,out] Buffer Buffer pointer + * @param[in] Pcie PCIe configuration info + */ +VOID +STATIC +GfxIntAudioEpEnumCallback ( + IN PCIe_ENGINE_CONFIG *Engine, + IN OUT VOID *Buffer, + IN PCIe_PLATFORM_CONFIG *Pcie + ) +{ + UINT8 *AudioCount; + AudioCount = (UINT8*) Buffer; + if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeHDMI) { + IDS_HDT_CONSOLE (GNB_TRACE, "Found HDMI Connector\n"); + (*AudioCount)++; + } else if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDP) { + if ((Engine->Type.Ddi.DdiData.Flags & DDI_DATA_FLAGS_DP1_1_ONLY) == 0) { + IDS_HDT_CONSOLE (GNB_TRACE, "Found DP1.2 Connector\n"); + *AudioCount += 4; + } else { + IDS_HDT_CONSOLE (GNB_TRACE, "Found DP1.1 Connector\n"); + (*AudioCount)++; + } + } + IDS_HDT_CONSOLE (GNB_TRACE, "New AudioCount = %d\n", *AudioCount); +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Enumerate audio endpoint in all display connectors. + * + * + * + * @param[in] Gfx Gfx configuration info + * @param[in, out] AudioEPCount Total Audio endpoint number + * @retval AGESA_STATUS + */ +AGESA_STATUS +GfxIntAudioEPEnumV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN OUT UINT8 *AudioEPCount + ) +{ + UINT8 NumAudioEp; + AGESA_STATUS Status; + PCIe_PLATFORM_CONFIG *Pcie; + + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV3 Enter\n"); + + NumAudioEp = 0; + Status = PcieLocateConfigurationData (GnbLibGetHeader (Gfx), &Pcie); + if ((Status == AGESA_SUCCESS) && (Gfx->GnbHdAudio != 0)) { + PcieConfigRunProcForAllEngines ( + DESCRIPTOR_ALLOCATED | DESCRIPTOR_DDI_ENGINE | DESCRIPTOR_VIRTUAL, + GfxIntAudioEpEnumCallback, + &NumAudioEp, + Pcie + ); + + if (Gfx->GnbRemoteDisplaySupport) { + NumAudioEp++; + } + } + + *AudioEPCount = NumAudioEp; + IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntAudioEPEnumV3 Exit\n"); + return Status; +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h new file mode 100644 index 0000000000..1c7938d0e9 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h @@ -0,0 +1,70 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Various GFX service procedures + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 84150 $ @e \$Date: 2012-12-12 15:46:25 -0600 (Wed, 12 Dec 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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. +* *************************************************************************** +* +*/ +#ifndef _GFXLIBV3_H_ +#define _GFXLIBV3_H_ + +UINT32 +GfxLibExtractDramFrequencyV3 ( + IN UINT8 Encoding, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +AGESA_STATUS +GfxEnableGmmAccessV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx + ); + +AGESA_STATUS +GfxRequestGPUPowerV3 ( + IN OUT GFX_PLATFORM_CONFIG *Gfx, + IN UINT8 PowerControl + ); + +AGESA_STATUS +GfxIntAudioEPEnumV3 ( + IN GFX_PLATFORM_CONFIG *Gfx, + IN OUT UINT8 *AudioEPCount + ); +#endif diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c new file mode 100644 index 0000000000..4e83c44359 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c @@ -0,0 +1,1233 @@ +/* $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: 67269 $ @e \$Date: 2012-03-26 02:53:08 -0500 (Mon, 26 Mar 2012) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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 "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbF1Table.h" +#include "GnbPcie.h" +#include "GnbGfx.h" +#include "GnbGfxFamServices.h" +#include "GnbCommonLib.h" +#include "GfxPwrPlayTable.h" +#include "Filecode.h" +#define FILECODE PROC_GNB_MODULES_GNBGFXINTTABLEV3_GFXPWRPLAYTABLE_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 + *---------------------------------------------------------------------------------------- + */ + +/// Software state +typedef struct { + BOOLEAN Valid; ///< State valid + UINT16 Classification; ///< State classification + UINT32 CapsAndSettings; ///< State capability and settings + UINT16 Classification2; ///< State classification2 + UINT32 SW_STATE_fld4; + UINT32 SW_STATE_fld5; + UINT8 SW_STATE_fld6; + UINT8 SW_STATE_fld7[10]; +} SW_STATE; + +typedef struct { + BOOLEAN Valid; + UINT32 GfxPwrPlayTable120_STRUCT_fld1; + UINT8 Vid; + UINT16 Tdp; +} GfxPwrPlayTable120_STRUCT; + +typedef struct { + GFX_PLATFORM_CONFIG *Gfx; + ATOM_PPLIB_POWERPLAYTABLE4 *PpTable; + PP_F1_ARRAY_V2 *PpF1s; + SW_STATE SwStateArray [MAX_NUM_OF_SW_STATES]; ///< SW state array + GfxPwrPlayTable120_STRUCT PP_WORKSPACE_V2_fld4[10]; + UINT8 NumOfClockVoltageLimitEnties; /// + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD VceClockVoltageLimitArray[MAX_NUM_OF_VCE_CLK_STATES]; + UINT8 NumOfVceClockEnties; + GfxPwrPlayTable204_STRUCT VceClockInfoArray[MAX_NUM_OF_VCE_CLK_STATES]; + UINT8 NumOfVceStateEntries; + ATOM_PPLIB_VCE_STATE_RECORD VceStateArray[MAX_NUM_OF_VCE_STATES]; ///< VCE state array + UINT8 NumOfUvdClkVoltLimitEntries; /// + ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD UvdClkVoltLimitArray[MAX_NUM_OF_UVD_CLK_STATES]; + UINT8 NumOfUvdClockEntries; + GfxPwrPlayTable261_STRUCT UvdClockInfoArray[MAX_NUM_OF_UVD_CLK_STATES]; + UINT8 PP_WORKSPACE_V2_fld15; /// + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD PP_WORKSPACE_V2_fld16[MAX_NUM_OF_SAMCLK_STATES]; + UINT8 PP_WORKSPACE_V2_fld17; /// + GfxPwrPlayTable310_STRUCT PP_WORKSPACE_V2_fld18[5]; +} PP_WORKSPACE_V2; + +/*---------------------------------------------------------------------------------------- + * 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 + *---------------------------------------------------------------------------------------- + */ + +VOID +GfxIntDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE4 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +/*----------------------------------------------------------------------------------------*/ +/** + * Create new software state + * + * + * @param[in, out] PpWorkspace PP workspace + * @retval Pointer to state entry in SW state array + */ + +STATIC SW_STATE * +GfxPwrPlayCreateSwState ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINTN Index; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid == FALSE) { + PpWorkspace->SwStateArray[Index].Valid = TRUE; + return &(PpWorkspace->SwStateArray[Index]); + } + } + return NULL; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable192_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT8 Vid + ) +{ + UINT8 Index; + + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid == FALSE) { + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 = fv1; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid = Vid; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid = TRUE; + PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Tdp = 0; + return Index; + } + } + return 0; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable224_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT8 Vid + ) +{ + UINT8 Index; + + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid && + fv1 == PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 && + Vid == PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid) { + + return Index; + } + } + + Index = GfxPwrPlayTable192_fun (PpWorkspace, fv1, Vid); + + return Index; +} + + +STATIC VOID +GfxPwrPlayTable256_fun ( + IN OUT SW_STATE *SwStateArray, + IN UINT8 DpmStateIndex + ) +{ + SwStateArray->SW_STATE_fld7[SwStateArray->SW_STATE_fld6++] = DpmStateIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy SW state info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ +STATIC VOID * +GfxPwrPlayAttachStateInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 SwStateIndex; + STATE_ARRAY *StateArray; + ATOM_PPLIB_STATE_V2 *States; + StateArray = (STATE_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + States = &StateArray->States[0]; + SwStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid && PpWorkspace->SwStateArray[Index].SW_STATE_fld6 != 0) { + States->nonClockInfoIndex = SwStateIndex; + States->ATOM_PPLIB_STATE_V2_fld0 = PpWorkspace->SwStateArray[Index].SW_STATE_fld6; + LibAmdMemCopy ( + &States->ClockInfoIndex[0], + PpWorkspace->SwStateArray[Index].SW_STATE_fld7, + PpWorkspace->SwStateArray[Index].SW_STATE_fld6, + GnbLibGetHeader (PpWorkspace->Gfx) + ); + States = (ATOM_PPLIB_STATE_V2*) ((UINT8*) States + sizeof (ATOM_PPLIB_STATE_V2) + sizeof (UINT8) * (States->ATOM_PPLIB_STATE_V2_fld0 - 1)); + SwStateIndex++; + } + } + StateArray->ucNumEntries = SwStateIndex; + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + (USHORT) ((UINT8 *) States - (UINT8 *) StateArray); + return StateArray; +} +/*----------------------------------------------------------------------------------------*/ +/** + * Copy clock info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + CLOCK_INFO_ARRAY *ClockInfoArray; + UINT8 Index; + UINT8 ClkStateIndex; + ClkStateIndex = 0; + ClockInfoArray = (CLOCK_INFO_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + for (Index = 0; Index < 10; Index++) { + if (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Valid == TRUE) { + ClockInfoArray->ClockInfo[ClkStateIndex].ucEngineClockHigh = (UINT8) (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1 >> 16); + ClockInfoArray->ClockInfo[ClkStateIndex].usEngineClockLow = (UINT16) (PpWorkspace->PP_WORKSPACE_V2_fld4[Index].GfxPwrPlayTable120_STRUCT_fld1); + ClockInfoArray->ClockInfo[ClkStateIndex].vddcIndex = PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Vid; + ClockInfoArray->ClockInfo[ClkStateIndex].ATOM_PPLIB_SUMO_CLOCK_INFO_fld3 = PpWorkspace->PP_WORKSPACE_V2_fld4[Index].Tdp; + ClkStateIndex++; + } + } + ClockInfoArray->ucNumEntries = ClkStateIndex; + ClockInfoArray->ucEntrySize = sizeof (GfxPwrPlayTable143_STRUCT); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (CLOCK_INFO_ARRAY) + sizeof (GfxPwrPlayTable143_STRUCT) * ClkStateIndex - sizeof (GfxPwrPlayTable143_STRUCT); + return ClockInfoArray; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Copy non clock info to PPTable + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachNonClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + NON_CLOCK_INFO_ARRAY *NonClockInfoArray; + UINT8 Index; + UINT8 NonClkStateIndex; + + NonClockInfoArray = (NON_CLOCK_INFO_ARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + NonClkStateIndex = 0; + for (Index = 0; Index < MAX_NUM_OF_SW_STATES; Index++) { + if (PpWorkspace->SwStateArray[Index].Valid && PpWorkspace->SwStateArray[Index].SW_STATE_fld6 != 0) { + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification = PpWorkspace->SwStateArray[Index].Classification; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ulCapsAndSettings = PpWorkspace->SwStateArray[Index].CapsAndSettings; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].usClassification2 = PpWorkspace->SwStateArray[Index].Classification2; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ATOM_PPLIB_NONCLOCK_INFO_fld7 = PpWorkspace->SwStateArray[Index].SW_STATE_fld5; + NonClockInfoArray->NonClockInfo[NonClkStateIndex].ATOM_PPLIB_NONCLOCK_INFO_fld6 = PpWorkspace->SwStateArray[Index].SW_STATE_fld4; + NonClkStateIndex++; + } + } + NonClockInfoArray->ucNumEntries = NonClkStateIndex; + NonClockInfoArray->ucEntrySize = sizeof (ATOM_PPLIB_NONCLOCK_INFO); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (NON_CLOCK_INFO_ARRAY) + sizeof (ATOM_PPLIB_NONCLOCK_INFO) * NonClkStateIndex - sizeof (ATOM_PPLIB_NONCLOCK_INFO); + return NonClockInfoArray; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Check if state valid + * + * + * @param[out] Index State index + * @param[in] PpF1s Pointer + * @param[in] Gfx Gfx configuration info + * @retval TRUE State is valid + */ +STATIC BOOLEAN +GfxPwrPlayIsF1dStateValid ( + IN UINT8 Index, + IN PP_F1_ARRAY_V2 *PpF1s, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + BOOLEAN Result; + Result = FALSE; + if ((PpF1s->PP_FUSE_ARRAY_V2_fld37 & (1 << Index)) || (PpF1s->PP_FUSE_ARRAY_V2_fld38 & (1 << Index))) { + Result = TRUE; + } + return Result; +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayTable437_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 ClkStateIndex; + UINT8 DpmF1Index; + UINT32 fv2; + SW_STATE *State; + PP_F1_ARRAY_V2 *PpF1s; + + PpF1s = PpWorkspace->PpF1s; + + // Create Battery state + State = GfxPwrPlayCreateSwState (PpWorkspace); + + State->Classification = ATOM_PPLIB_CLASSIFICATION_UI_BATTERY; + State->Classification2 = 0; + State->SW_STATE_fld4 = 0; + State->SW_STATE_fld5 = 0; + if (PpWorkspace->Gfx->AbmSupport != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_VARIBRIGHT; + } + if (PpWorkspace->Gfx->DynamicRefreshRate != 0) { + State->CapsAndSettings |= ATOM_PPLIB_ENABLE_DRR; + } + + for (DpmF1Index = 0; DpmF1Index < 5; DpmF1Index++) { + + if (PpF1s->PP_FUSE_ARRAY_V2_fld38 & (1 << DpmF1Index)) { + + fv2 = (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index] != 0) ? + GfxFmCalculateClock (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index], + GnbLibGetHeader (PpWorkspace->Gfx)) : 0; + + if (fv2 != 0) { + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, PpF1s->PP_FUSE_ARRAY_V2_fld32[DpmF1Index]); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + } + } + } + + // Create Performance state + State = GfxPwrPlayCreateSwState (PpWorkspace); + + State->Classification = ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE; + State->Classification2 = 0; + State->SW_STATE_fld4 = 0; + State->SW_STATE_fld5 = 0; + + // Loop through fused DPM states and find those that go with Performance + for (DpmF1Index = 0; DpmF1Index < 5; DpmF1Index++) { + + if (PpF1s->PP_FUSE_ARRAY_V2_fld37 & (1 << DpmF1Index)) { + + fv2 = (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index] != 0) ? + GfxFmCalculateClock (PpF1s->PP_FUSE_ARRAY_V2_fld33[DpmF1Index], + GnbLibGetHeader (PpWorkspace->Gfx)) : 0; + + if (fv2 != 0) { + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, PpF1s->PP_FUSE_ARRAY_V2_fld32[DpmF1Index]); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + } + } + } + + // Create Boot State + State = GfxPwrPlayCreateSwState (PpWorkspace); + State->Classification = ATOM_PPLIB_CLASSIFICATION_BOOT; + fv2 = 200 * 100; + ClkStateIndex = GfxPwrPlayTable224_fun (PpWorkspace, fv2, 0); + GfxPwrPlayTable256_fun (State, ClkStateIndex); + +} + + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayAddEclkState ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 Eclk + ) +{ + UINT8 Index; + USHORT EclkLow; + UCHAR EclkHigh; + EclkLow = (USHORT) (Eclk & 0xffff); + EclkHigh = (UCHAR) (Eclk >> 16); + for (Index = 0; Index < PpWorkspace->NumOfVceClockEnties; Index++) { + if (PpWorkspace->VceClockInfoArray[Index].ucECClkHigh == EclkHigh && PpWorkspace->VceClockInfoArray[Index].usECClkLow == EclkLow) { + return Index; + } + } + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].ucECClkHigh = EclkHigh; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].usECClkLow = EclkLow; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].GfxPwrPlayTable204_STRUCT_fld1 = EclkHigh; + PpWorkspace->VceClockInfoArray[PpWorkspace->NumOfVceClockEnties].GfxPwrPlayTable204_STRUCT_fld0 = EclkLow; + return PpWorkspace->NumOfVceClockEnties++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add ECLK state + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] EclkIndex ECLK index + * @param[in] Vid Vid index + * @retval Index of state entry in Eclk Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddEclkVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 EclkIndex, + IN UINT8 Vid + ) +{ + UINT8 Index; + for (Index = 0; Index < PpWorkspace->NumOfClockVoltageLimitEnties; Index++) { + if (PpWorkspace->VceClockVoltageLimitArray[Index].ucVCEClockInfoIndex == EclkIndex) { + return Index; + } + } + PpWorkspace->VceClockVoltageLimitArray[PpWorkspace->NumOfClockVoltageLimitEnties].ucVCEClockInfoIndex = EclkIndex; + PpWorkspace->VceClockVoltageLimitArray[PpWorkspace->NumOfClockVoltageLimitEnties].usVoltage = Vid; + return PpWorkspace->NumOfClockVoltageLimitEnties++; +} + + +/*----------------------------------------------------------------------------------------*/ + +STATIC UINT8 +GfxPwrPlayTable588_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT32 fv1, + IN UINT32 fv2 + ) +{ + UINT8 Index; + USHORT v1; + UCHAR v2; + USHORT v3; + UCHAR v4; + v1 = (USHORT) (fv1 & 0xffff); + v2 = (UCHAR) (fv1 >> 16); + v3 = (USHORT) (fv2 & 0xffff); + v4 = (UCHAR) (fv2 >> 16); + for (Index = 0; Index < PpWorkspace->NumOfUvdClockEntries; Index++) { + if (PpWorkspace->UvdClockInfoArray[Index].GfxPwrPlayTable261_STRUCT_fld1 == v2 && + PpWorkspace->UvdClockInfoArray[Index].GfxPwrPlayTable261_STRUCT_fld0 == v1) { + return Index; + } + } + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld1 = v2; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld0 = v1; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld3 = v4; + PpWorkspace->UvdClockInfoArray[PpWorkspace->NumOfUvdClockEntries].GfxPwrPlayTable261_STRUCT_fld2 = v3; + return PpWorkspace->NumOfUvdClockEntries++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add Uvd voltage record + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] ClkIndex CLK index + * @param[in] Vid Vid index + * @retval Index of state entry in Eclk Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddUvdVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 ClkIndex, + IN UINT8 Vid + ) +{ + UINT8 Index; + for (Index = 0; Index < PpWorkspace->NumOfUvdClkVoltLimitEntries; Index++) { + if (PpWorkspace->UvdClkVoltLimitArray[Index].ucUVDClockInfoIndex == ClkIndex) { + return Index; + } + } + PpWorkspace->UvdClkVoltLimitArray[PpWorkspace->NumOfUvdClkVoltLimitEntries].ucUVDClockInfoIndex = + ClkIndex; + PpWorkspace->UvdClkVoltLimitArray[PpWorkspace->NumOfUvdClkVoltLimitEntries].usVoltage = Vid; + return PpWorkspace->NumOfUvdClkVoltLimitEntries++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Add Samu voltage record + * + * + * @param[in, out] PpWorkspace PP workspace + * @param[in] Vid Vid + * @param[in] Samclk CLK associated with the Vid + * @retval Index of state entry in Voltage record array + */ + +STATIC UINT8 +GfxPwrPlayAddSamuVoltageRecord ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace, + IN UINT8 Vid, + IN UINT32 Samclk + ) +{ + UINT8 Index; + USHORT SamclkLow; + UCHAR SamclkHigh; + SamclkLow = (USHORT) (Samclk & 0xffff); + SamclkHigh = (UCHAR) (Samclk >> 16); + for (Index = 0; Index < PpWorkspace->PP_WORKSPACE_V2_fld15; Index++) { + if ((PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usSAMClockHigh == SamclkHigh) && + (PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usSAMClockLow == SamclkLow) && + (PpWorkspace->PP_WORKSPACE_V2_fld16[Index].usVoltage == Vid) + ) { + return Index; + } + } + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usSAMClockHigh = + SamclkHigh; + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usSAMClockLow = + SamclkLow; + PpWorkspace->PP_WORKSPACE_V2_fld16[PpWorkspace->PP_WORKSPACE_V2_fld15].usVoltage = Vid; + return PpWorkspace->PP_WORKSPACE_V2_fld15++; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach extended header + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachExtendedHeaderBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) + ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + ExtendedHeader->usSize = sizeof (ATOM_PPLIB_EXTENDEDHEADER); + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_EXTENDEDHEADER); + return ExtendedHeader; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Vce Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_TABLE *VceTable; + VceTable = (ATOM_PPLIB_VCE_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_VCE_TABLE); + return VceTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE clock info block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + VCECLOCKINFOARRAY *VceClockInfoArray; + VceClockInfoArray = (VCECLOCKINFOARRAY *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceClockInfoArray->ucNumEntries = PpWorkspace->NumOfVceClockEnties; + LibAmdMemCopy ( + &VceClockInfoArray->entries[0], + &PpWorkspace->VceClockInfoArray[0], + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (VCECLOCKINFOARRAY) + + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT) - + sizeof (GfxPwrPlayTable204_STRUCT); + return VceClockInfoArray; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *VceClockVoltageLimitTable; + VceClockVoltageLimitTable = (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceClockVoltageLimitTable->numEntries = PpWorkspace->NumOfClockVoltageLimitEnties; + LibAmdMemCopy ( + &VceClockVoltageLimitTable->entries[0], + &PpWorkspace->VceClockVoltageLimitArray[0], + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE) + + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD); + return VceClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach VCE state block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachVceStateTableBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_VCE_STATE_TABLE *VceStateTable; + VceStateTable = (ATOM_PPLIB_VCE_STATE_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + VceStateTable->numEntries = PpWorkspace->NumOfVceStateEntries; + LibAmdMemCopy ( + &VceStateTable->entries[0], + &PpWorkspace->VceStateArray[0], + VceStateTable->numEntries * sizeof (ATOM_PPLIB_VCE_STATE_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_VCE_STATE_TABLE) + + VceStateTable->numEntries * sizeof (ATOM_PPLIB_VCE_STATE_RECORD) - + sizeof (ATOM_PPLIB_VCE_STATE_RECORD); + return VceStateTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Uvd Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_UVD_TABLE *UvdTable; + UvdTable = (ATOM_PPLIB_UVD_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_UVD_TABLE); + return UvdTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach UVD clock info block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdClockInfoBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + GfxPwrPlayTable267_STRUCT *UvdClockInfoArray; + UvdClockInfoArray = (GfxPwrPlayTable267_STRUCT *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdClockInfoArray->ucNumEntries = PpWorkspace->NumOfUvdClockEntries; + LibAmdMemCopy ( + &UvdClockInfoArray->entries[0], + &PpWorkspace->UvdClockInfoArray[0], + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (GfxPwrPlayTable267_STRUCT) + + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT) - + sizeof (GfxPwrPlayTable261_STRUCT); + return UvdClockInfoArray; +} + + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach UVD voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachUvdVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UVD_CLK_VOLT_LIMIT_TABLE *UvdClockVoltageLimitTable; + UvdClockVoltageLimitTable = (UVD_CLK_VOLT_LIMIT_TABLE *) ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + UvdClockVoltageLimitTable->numEntries = PpWorkspace->NumOfUvdClkVoltLimitEntries; + LibAmdMemCopy ( + &UvdClockVoltageLimitTable->entries[0], + &PpWorkspace->UvdClkVoltLimitArray[0], + UvdClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (UVD_CLK_VOLT_LIMIT_TABLE) + + UvdClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD); + return UvdClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach SAMU Rev Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachSamuTableRevBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_SAMU_TABLE *VceTable; + VceTable = (ATOM_PPLIB_SAMU_TABLE *) ((UINT8 *) PpWorkspace->PpTable + + PpWorkspace->PpTable->sHeader.usStructureSize); + VceTable->revid = 0; + PpWorkspace->PpTable->sHeader.usStructureSize += sizeof (ATOM_PPLIB_SAMU_TABLE); + return VceTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach SAMU voltage limit block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayAttachSamuVoltageLimitBlock ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *SamuClockVoltageLimitTable; + SamuClockVoltageLimitTable = (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *) + ((UINT8 *) PpWorkspace->PpTable + PpWorkspace->PpTable->sHeader.usStructureSize); + SamuClockVoltageLimitTable->numEntries = PpWorkspace->PP_WORKSPACE_V2_fld15; + LibAmdMemCopy ( + &SamuClockVoltageLimitTable->entries[0], + &PpWorkspace->PP_WORKSPACE_V2_fld16[0], + SamuClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE) + + SamuClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD); + return SamuClockVoltageLimitTable; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Attach Sclk Volt Dep Block + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID * +GfxPwrPlayTable956_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + GfxPwrPlayTable316_STRUCT *v0; + + v0 = (GfxPwrPlayTable316_STRUCT *) + ((UINT8 *) PpWorkspace->PpTable + + PpWorkspace->PpTable->sHeader.usStructureSize); + v0->numEntries = PpWorkspace->PP_WORKSPACE_V2_fld17; + LibAmdMemCopy ( + &v0->entries[0], + &PpWorkspace->PP_WORKSPACE_V2_fld18[0], + 5 * sizeof (GfxPwrPlayTable310_STRUCT), + GnbLibGetHeader (PpWorkspace->Gfx) + ); + PpWorkspace->PpTable->sHeader.usStructureSize = + PpWorkspace->PpTable->sHeader.usStructureSize + + sizeof (GfxPwrPlayTable316_STRUCT) + + v0->numEntries * sizeof (GfxPwrPlayTable310_STRUCT) - + sizeof (GfxPwrPlayTable310_STRUCT); + + + return v0; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build VCE state info + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID +GfxPwrPlayBuildVceStateTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 VceStateIndex; + UINT8 Vid; + UINT32 Eclk; + UINT32 v4; + UINT8 UsedStateBitmap; + UsedStateBitmap = 0; + // build used state + for (Index = 0; + Index < (sizeof (PpWorkspace->PpF1s->VceFlags) / + sizeof (PpWorkspace->PpF1s->VceFlags[0])) ; + Index++) { + UsedStateBitmap |= PpWorkspace->PpF1s->VceFlags[Index]; + for (VceStateIndex = 0; + VceStateIndex < (sizeof (PpWorkspace->VceStateArray) / + sizeof (PpWorkspace->VceStateArray[0])); + VceStateIndex++) { + if ((PpWorkspace->PpF1s->VceFlags[Index] & (1 << VceStateIndex)) != 0) { + v4 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld33[PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld16[Index]], + GnbLibGetHeader (PpWorkspace->Gfx)); + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld16[Index]]; + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex = + GfxPwrPlayTable224_fun (PpWorkspace, v4, Vid); + if (PpWorkspace->PpF1s->VceMclk) { + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex |= + (PpWorkspace->PpF1s->VceMclk << 6); + } + Eclk = GfxFmCalculateClock (PpWorkspace->PpF1s->EclkDid[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex = + GfxPwrPlayAddEclkState (PpWorkspace, Eclk); + GfxPwrPlayAddEclkVoltageRecord (PpWorkspace, + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex, Vid); + PpWorkspace->NumOfVceStateEntries++; + } + } + } + //build unused states + for (VceStateIndex = 0; + VceStateIndex < (sizeof (PpWorkspace->VceStateArray) / sizeof (PpWorkspace->VceStateArray[0])); + VceStateIndex++) { + if ((UsedStateBitmap & (1 << VceStateIndex)) == 0) { + PpWorkspace->VceStateArray[VceStateIndex].ucClockInfoIndex = 0; + PpWorkspace->VceStateArray[VceStateIndex].ucVCEClockInfoIndex = GfxPwrPlayAddEclkState (PpWorkspace, 0); + PpWorkspace->NumOfVceStateEntries++; + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayBuildUvdClockTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 Index; + UINT8 Vid; + UINT32 v2; + UINT32 v3; + UINT8 UsedStateBitmap; + UINT8 UvdIndex; + + UsedStateBitmap = 0; + // build used state + for (Index = 0; Index < MAX_NUM_OF_UVD_CLK_STATES ; Index++) { + if (GfxPwrPlayIsF1dStateValid (Index, PpWorkspace->PpF1s, PpWorkspace->Gfx)) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[Index]; + v2 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld1[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + v3 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld2[Index], + GnbLibGetHeader (PpWorkspace->Gfx)); + UvdIndex = GfxPwrPlayTable588_fun (PpWorkspace, v2, v3); + GfxPwrPlayAddUvdVoltageRecord (PpWorkspace, + UvdIndex, Vid); + } + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build SAMU info + * + * + * @param[in, out] PpWorkspace PP workspace + */ + +STATIC VOID +GfxPwrPlayBuildSamuTable ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 SamuIndex; + UINT8 Vid; + UINT32 Samuclk; + UINT8 UsedStateBitmap; + UsedStateBitmap = 0; + // build used state + for (SamuIndex = 0; SamuIndex < MAX_NUM_OF_SAMCLK_STATES; SamuIndex++) { + if (GfxPwrPlayIsF1dStateValid (SamuIndex, PpWorkspace->PpF1s, PpWorkspace->Gfx)) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[SamuIndex]; + Samuclk = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld34[SamuIndex], + GnbLibGetHeader (PpWorkspace->Gfx)); + GfxPwrPlayAddSamuVoltageRecord (PpWorkspace, Vid, Samuclk); + } + } +} + +/*----------------------------------------------------------------------------------------*/ + +STATIC VOID +GfxPwrPlayTable1122_fun ( + IN OUT PP_WORKSPACE_V2 *PpWorkspace + ) +{ + UINT8 v0; + UINT8 Vid; + UINT32 v2; + USHORT v3; + UCHAR v4; + + // build the table + for (v0 = 0; v0 < 5; v0++) { + Vid = PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld32[v0]; + v2 = GfxFmCalculateClock (PpWorkspace->PpF1s->PP_FUSE_ARRAY_V2_fld33[v0], + GnbLibGetHeader (PpWorkspace->Gfx)); + ASSERT (Vid != 0) + ASSERT (v2 != 0) + v3 = (USHORT) (v2 & 0xffff); + v4 = (UCHAR) (v2 >> 16); + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld2 = Vid; + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld1 = v4; + PpWorkspace->PP_WORKSPACE_V2_fld18[v0].GfxPwrPlayTable310_fld0 = v3; + PpWorkspace->PP_WORKSPACE_V2_fld17++; + } +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Build PP table + * + * + * @param[out] Buffer Buffer to create PP table + * @param[in] Gfx Gfx configuration info + * @retval AGESA_SUCCESS + * @retval AGESA_ERROR + */ + +AGESA_STATUS +GfxPwrPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + PP_WORKSPACE_V2 PpWorkspace; + VOID *BlockPtr; + + LibAmdMemFill (&PpWorkspace, 0x00, sizeof (PP_WORKSPACE_V2), GnbLibGetHeader (Gfx)); + PpWorkspace.PpF1s = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Gfx)); + ASSERT (PpWorkspace.PpF1s != NULL); + if (PpWorkspace.PpF1s == NULL) { + return AGESA_ERROR; + } + + PpWorkspace.PpTable = (ATOM_PPLIB_POWERPLAYTABLE4 *) Buffer; + PpWorkspace.Gfx = Gfx; + //Fill static info + PpWorkspace.PpTable->sHeader.ucTableFormatRevision = 6; + PpWorkspace.PpTable->sHeader.ucTableContentRevision = 1; + PpWorkspace.PpTable->ucDataRevision = PpWorkspace.PpF1s->PPlayTableRev; + PpWorkspace.PpTable->sThermalController.ucType = ATOM_PP_THERMALCONTROLLER_KV; + PpWorkspace.PpTable->sThermalController.ucFanParameters = ATOM_PP_FANPARAMETERS_NOFAN; + PpWorkspace.PpTable->sHeader.usStructureSize = sizeof (ATOM_PPLIB_POWERPLAYTABLE4); + PpWorkspace.PpTable->usTableSize = sizeof (ATOM_PPLIB_POWERPLAYTABLE4); + PpWorkspace.PpTable->usFormatID = 0x13; + if ((Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) != 0) { + PpWorkspace.PpTable->ulPlatformCaps |= ATOM_PP_PLATFORM_CAP_POWERPLAY; + } + + + GfxPwrPlayTable437_fun (&PpWorkspace); + + // Fill Eclk state info + if (PpWorkspace.PpF1s->PP_FUSE_ARRAY_V2_fld13) { + GfxPwrPlayBuildVceStateTable (&PpWorkspace); + GfxPwrPlayBuildUvdClockTable (&PpWorkspace); + GfxPwrPlayBuildSamuTable (&PpWorkspace); + GfxPwrPlayTable1122_fun (&PpWorkspace); + } + + //Copy state info to actual PP table + BlockPtr = GfxPwrPlayAttachStateInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usStateArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachClockInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usClockInfoArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachNonClockInfoBlock (&PpWorkspace); + PpWorkspace.PpTable->usNonClockInfoArrayOffset = (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + + if (PpWorkspace.PpF1s->PP_FUSE_ARRAY_V2_fld13) { + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ExtendedHeader = + (ATOM_PPLIB_EXTENDEDHEADER *) GfxPwrPlayAttachExtendedHeaderBlock (&PpWorkspace); + PpWorkspace.PpTable->usExtendendedHeaderOffset = + (USHORT) ((UINT8 *) ExtendedHeader - (UINT8 *) (PpWorkspace.PpTable)); + BlockPtr = GfxPwrPlayAttachVceTableRevBlock (&PpWorkspace); + ExtendedHeader->usVCETableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachVceClockInfoBlock (&PpWorkspace); + GfxPwrPlayAttachVceVoltageLimitBlock (&PpWorkspace); + GfxPwrPlayAttachVceStateTableBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayAttachUvdTableRevBlock (&PpWorkspace); + ExtendedHeader->usUVDTableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachUvdClockInfoBlock (&PpWorkspace); + GfxPwrPlayAttachUvdVoltageLimitBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayAttachSamuTableRevBlock (&PpWorkspace); + ExtendedHeader->usSAMUTableOffset = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + GfxPwrPlayAttachSamuVoltageLimitBlock (&PpWorkspace); + + BlockPtr = GfxPwrPlayTable956_fun (&PpWorkspace); + PpWorkspace.PpTable->ATOM_PPLIB_POWERPLAYTABLE4_fld17 = + (USHORT) ((UINT8 *) BlockPtr - (UINT8 *) (PpWorkspace.PpTable)); + + IDS_HDT_CONSOLE (GNB_TRACE, "ExtendedHeader \n"); + IDS_HDT_CONSOLE (GNB_TRACE, " VceTableOffset = %04x\n", ExtendedHeader->usVCETableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, " UvdTableOffset = %04x\n", ExtendedHeader->usUVDTableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, " SamTableOffset = %04x\n", ExtendedHeader->usSAMUTableOffset); + IDS_HDT_CONSOLE (GNB_TRACE, "\n"); + + } + GNB_DEBUG_CODE ( + GfxIntDebugDumpPpTable (PpWorkspace.PpTable, Gfx); + ); + + return AGESA_SUCCESS; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Dump PP table + * + * + * + * @param[in] PpTable Power Play table + * @param[in] Gfx Gfx configuration info + */ + +VOID +GfxIntDebugDumpPpTable ( + IN ATOM_PPLIB_POWERPLAYTABLE4 *PpTable, + IN GFX_PLATFORM_CONFIG *Gfx + ) +{ + UINTN Index; + STATE_ARRAY *StateArray; + ATOM_PPLIB_STATE_V2 *StatesPtr; + NON_CLOCK_INFO_ARRAY *NonClockInfoArrayPtr; + CLOCK_INFO_ARRAY *ClockInfoArrayPtr; + ATOM_PPLIB_EXTENDEDHEADER *ExtendedHeader; + ATOM_PPLIB_VCE_STATE_TABLE *VceStateTable; + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *VceClockVoltageLimitTable; + VCECLOCKINFOARRAY *VceClockInfoArray; + GfxPwrPlayTable267_STRUCT *UvdClockInfoArray; + UVD_CLK_VOLT_LIMIT_TABLE *UvdClockVoltLimitTable; + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *SamuClockVoltLimitTable; + UINT8 EclkIndex; + + IDS_HDT_CONSOLE (GFX_MISC, " < --- Power Play Table ------ > \n"); + IDS_HDT_CONSOLE (GFX_MISC, " Table Revision = %d\n", PpTable->ucDataRevision); + StateArray = (STATE_ARRAY *) ((UINT8 *) PpTable + PpTable->usStateArrayOffset); + StatesPtr = StateArray->States; + NonClockInfoArrayPtr = (NON_CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usNonClockInfoArrayOffset); + ClockInfoArrayPtr = (CLOCK_INFO_ARRAY *) ((UINT8 *) PpTable + PpTable->usClockInfoArrayOffset); + IDS_HDT_CONSOLE (GFX_MISC, " < --- SW State Table ---------> \n"); + for (Index = 0; Index < StateArray->ucNumEntries; Index++) { + IDS_HDT_CONSOLE (GFX_MISC, " State #%d\n", Index + 1 + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification + ); + IDS_HDT_CONSOLE (GFX_MISC, " Classification2 0x%x\n", + NonClockInfoArrayPtr->NonClockInfo[StatesPtr->nonClockInfoIndex].usClassification2 + ); + IDS_HDT_CONSOLE (GFX_MISC, "\n"); + StatesPtr = (ATOM_PPLIB_STATE_V2 *) ((UINT8 *) StatesPtr + sizeof (ATOM_PPLIB_STATE_V2) + StatesPtr->ATOM_PPLIB_STATE_V2_fld0 - 1); + } + if (PpTable->usExtendendedHeaderOffset != 0) { + ExtendedHeader = (ATOM_PPLIB_EXTENDEDHEADER *) ((UINT8 *) PpTable + + PpTable->usExtendendedHeaderOffset); + + IDS_HDT_CONSOLE (GNB_TRACE, "ExtendedHeader = %08x\n", ExtendedHeader); + + VceClockInfoArray = (VCECLOCKINFOARRAY *) ((UINT8 *) PpTable + + ExtendedHeader->usVCETableOffset + sizeof (ATOM_PPLIB_VCE_TABLE)); + VceClockVoltageLimitTable = + (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE *) ((UINT8 *) VceClockInfoArray + + sizeof (VCECLOCKINFOARRAY) + + VceClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable204_STRUCT) - + sizeof (GfxPwrPlayTable204_STRUCT)); + VceStateTable = + (ATOM_PPLIB_VCE_STATE_TABLE *) ((UINT8 *) VceClockVoltageLimitTable + + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE) + + VceClockVoltageLimitTable->numEntries * sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD) - + sizeof (ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD)); + UvdClockInfoArray = + (GfxPwrPlayTable267_STRUCT *) ((UINT8 *) PpTable + ExtendedHeader->usUVDTableOffset + + sizeof (ATOM_PPLIB_UVD_TABLE)); + UvdClockVoltLimitTable = + (UVD_CLK_VOLT_LIMIT_TABLE *) ((UINT8 *) UvdClockInfoArray + sizeof (GfxPwrPlayTable267_STRUCT) + + UvdClockInfoArray->ucNumEntries * sizeof (GfxPwrPlayTable261_STRUCT) - + sizeof (GfxPwrPlayTable261_STRUCT)); + SamuClockVoltLimitTable = + (ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE *) + ((UINT8 *) PpTable + ExtendedHeader->usSAMUTableOffset + sizeof (ATOM_PPLIB_SAMU_TABLE)); + + IDS_HDT_CONSOLE (GFX_MISC, " < --- VCE State Table [%d]--> \n", VceStateTable->numEntries); + + IDS_HDT_CONSOLE (GFX_MISC, " < --- VCE Voltage Record Table ---> \n"); + for (Index = 0; Index < VceClockVoltageLimitTable->numEntries; Index++) { + EclkIndex = VceClockVoltageLimitTable->entries[Index].ucVCEClockInfoIndex; + IDS_HDT_CONSOLE (GFX_MISC, " VCE Voltage Record #%d\n", Index + ); + IDS_HDT_CONSOLE (GFX_MISC, " ECLK = %d\n", + VceClockInfoArray->entries[EclkIndex].usECClkLow | (VceClockInfoArray->entries[EclkIndex].ucECClkHigh << 16) + ); + IDS_HDT_CONSOLE (GFX_MISC, " VID index = %d\n", + VceClockVoltageLimitTable->entries[Index].usVoltage + ); + } + + + IDS_HDT_CONSOLE (GFX_MISC, " < --- SAMU Voltage Record Table ---> \n"); + for (Index = 0; Index < SamuClockVoltLimitTable->numEntries; Index++) { + IDS_HDT_CONSOLE (GFX_MISC, " SAMU Voltage Record #%d\n", Index + ); + IDS_HDT_CONSOLE (GFX_MISC, " SAMCLK = %d\n", + SamuClockVoltLimitTable->entries[Index].usSAMClockLow | + (SamuClockVoltLimitTable->entries[Index].usSAMClockHigh << 16) + ); + IDS_HDT_CONSOLE (GFX_MISC, " VID index = %d\n", + SamuClockVoltLimitTable->entries[Index].usVoltage + ); + } + } + + IDS_HDT_CONSOLE (GFX_MISC, " PplayDumpExit\n"); + +} diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h new file mode 100644 index 0000000000..05895ced55 --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h @@ -0,0 +1,321 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * Service procedure to initialize Power Play Table + * + * + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: GNB + * @e \$Revision: 63366 $ @e \$Date: 2011-12-21 14:49:48 -0600 (Wed, 21 Dec 2011) $ + * + */ +/* +***************************************************************************** +* + * Copyright (c) 2008 - 2013, 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. +* *************************************************************************** +* +*/ +#ifndef _GFXPWRPLAYTABLE_H_ +#define _GFXPWRPLAYTABLE_H_ + +#pragma pack (push, 1) + +#define POLICY_LABEL_BATTERY 0x1 +#define POLICY_LABEL_PERFORMANCE 0x2 + +#define MAX_NUM_OF_SW_STATES 3 +#define MAX_NUM_OF_VCE_CLK_STATES 5 +#define MAX_NUM_OF_VCE_STATES 6 +#define MAX_NUM_OF_UVD_CLK_STATES 5 +#define MAX_NUM_OF_SAMCLK_STATES 5 +/// ATOM_PPLIB_POWERPLAYTABLE::ulPlatformCaps +#define ATOM_PP_PLATFORM_CAP_BACKBIAS 1 +#define ATOM_PP_PLATFORM_CAP_POWERPLAY 2 +#define ATOM_PP_PLATFORM_CAP_SBIOSPOWERSOURCE 4 +#define ATOM_PP_PLATFORM_CAP_ASPM_L0s 8 +#define ATOM_PP_PLATFORM_CAP_ASPM_L1 16 +#define ATOM_PP_PLATFORM_CAP_HARDWAREDC 32 +#define ATOM_PP_PLATFORM_CAP_GEMINIPRIMARY 64 +#define ATOM_PP_PLATFORM_CAP_STEPVDDC 128 +#define ATOM_PP_PLATFORM_CAP_VOLTAGECONTROL 256 +#define ATOM_PP_PLATFORM_CAP_SIDEPORTCONTROL 512 +#define ATOM_PP_PLATFORM_CAP_TURNOFFPLL_ASPML1 1024 +#define ATOM_PP_PLATFORM_CAP_HTLINKCONTROL 2048 +#define ATOM_PP_PLATFORM_CAP_MVDDCONTROL 4096 +#define ATOM_PP_PLATFORM_CAP_GOTO_BOOT_ON_ALERT 0x2000 // Go to boot state on alerts, e.g. on an AC->DC transition. +#define ATOM_PP_PLATFORM_CAP_DONT_WAIT_FOR_VBLANK_ON_ALERT 0x4000 // Do NOT wait for VBLANK during an alert (e.g. AC->DC transition). +#define ATOM_PP_PLATFORM_CAP_VDDCI_CONTROL 0x8000 // Does +#define ATOM_PP_PLATFORM_CAP_REGULATOR_HOT 0x00010000ul // Enable the 'regulator hot' feature. +#define ATOM_PP_PLATFORM_CAP_BACO 0x00020000ul // Does the driver supports BACO state. + + +#define ATOM_PPLIB_CLASSIFICATION_UI_BATTERY 1 +#define ATOM_PPLIB_CLASSIFICATION_UI_BALANCED 3 +#define ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE 5 + +#define ATOM_PPLIB_CLASSIFICATION_BOOT 0x0008 +#define ATOM_PPLIB_CLASSIFICATION_THERMAL 0x0010 +#define ATOM_PPLIB_CLASSIFICATION_LIMITEDPOWERSOURCE 0x0020 +#define ATOM_PPLIB_CLASSIFICATION_REST 0x0040 +#define ATOM_PPLIB_CLASSIFICATION_FORCED 0x0080 +#define ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE 0x0100 +#define ATOM_PPLIB_CLASSIFICATION_OVERDRIVETEMPLATE 0x0200 +#define ATOM_PPLIB_CLASSIFICATION_UVDSTATE 0x0400 +#define ATOM_PPLIB_CLASSIFICATION_3DLOW 0x0800 +#define ATOM_PPLIB_CLASSIFICATION_ACPI 0x1000 +#define ATOM_PPLIB_CLASSIFICATION_HD2STATE 0x2000 +#define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 +#define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 +#define ATOM_PPLIB_CLASSIFICATION_NONUVDSTATE 0x0000 + +#define ATOM_PPLIB_CLASSIFICATION2_MVC 0x0004 //Multi-View + +#define ATOM_PPLIB_ENABLE_VARIBRIGHT 0x00008000ul +#define ATOM_PPLIB_ENABLE_DRR 0x00080000ul + +#define ATOM_PP_FANPARAMETERS_NOFAN 0x80 +#define ATOM_PP_THERMALCONTROLLER_KV 0x13 + +typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO { + USHORT usEngineClockLow; + UCHAR ucEngineClockHigh; + UCHAR vddcIndex; + USHORT ATOM_PPLIB_SUMO_CLOCK_INFO_fld3; + USHORT rsv1; + ULONG rsv2[2]; +} GfxPwrPlayTable143_STRUCT; + +/// Non clock info +typedef struct _ATOM_PPLIB_NONCLOCK_INFO { + USHORT usClassification; ///< State classification see ATOM_PPLIB_CLASSIFICATION_* + UCHAR ucMinTemperature; ///< Reserved + UCHAR ucMaxTemperature; ///< Reserved + ULONG ulCapsAndSettings; ///< Capability Setting (ATOM_PPLIB_ENABLE_DRR or ATOM_PPLIB_ENABLE_VARIBRIGHT or 0) + UCHAR ucRequiredPower; ///< Reserved + USHORT usClassification2; ///< Reserved + ULONG ATOM_PPLIB_NONCLOCK_INFO_fld6; + ULONG ATOM_PPLIB_NONCLOCK_INFO_fld7; + UCHAR ucUnused[5]; ///< Reserved +} ATOM_PPLIB_NONCLOCK_INFO; + +/// Thermal controller info stub +typedef struct _ATOM_PPLIB_THERMALCONTROLLER { + UCHAR ucType; ///< Reserved. Should be set 0xE + UCHAR ucI2cLine; ///< Reserved. Should be set 0 + UCHAR ucI2cAddress; ///< Reserved. Should be set 0 + UCHAR ucFanParameters; ///< Reserved. Should be set 0x80 + UCHAR ucFanMinRPM; ///< Reserved. Should be set 0 + UCHAR ucFanMaxRPM; ///< Reserved. Should be set 0 + UCHAR ucReserved; ///< Reserved. Should be set 0 + UCHAR ucFlags; ///< Reserved. Should be set 0 +} ATOM_PPLIB_THERMALCONTROLLER; + +/// SW state info +typedef struct _ATOM_PPLIB_STATE_V2 { + UCHAR ATOM_PPLIB_STATE_V2_fld0; + UCHAR nonClockInfoIndex; ///< Index to the array of NonClockInfos + UCHAR ClockInfoIndex[1]; ///< Array of DPM states. Actual number calculated during state enumeration +} ATOM_PPLIB_STATE_V2; + +/// SW state Array +typedef struct { + UCHAR ucNumEntries; ///< Number of SW states + ATOM_PPLIB_STATE_V2 States[1]; ///< SW state info. Actual number calculated during state enumeration +} STATE_ARRAY; + +/// Clock info Array +typedef struct { + UCHAR ucNumEntries; ///< Number of ClockInfo entries + UCHAR ucEntrySize; + GfxPwrPlayTable143_STRUCT ClockInfo[1]; +} CLOCK_INFO_ARRAY; + +/// Non clock info Array +typedef struct { + + UCHAR ucNumEntries; ///< Number of Entries; + UCHAR ucEntrySize; ///< Size of NonClockInfo + ATOM_PPLIB_NONCLOCK_INFO NonClockInfo[1]; ///< Non clock info array +} NON_CLOCK_INFO_ARRAY; + +/// VCE clock info +typedef struct { + USHORT GfxPwrPlayTable204_STRUCT_fld0; + UCHAR GfxPwrPlayTable204_STRUCT_fld1; + USHORT usECClkLow; + UCHAR ucECClkHigh; +} GfxPwrPlayTable204_STRUCT; + +/// VCE clock info array +typedef struct { + UCHAR ucNumEntries; + GfxPwrPlayTable204_STRUCT entries[1]; +} VCECLOCKINFOARRAY; + +/// VCE voltage limit record +typedef struct { + USHORT usVoltage; ///< Voltage index + UCHAR ucVCEClockInfoIndex; ///< Index of VCE clock state +} ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD; + +/// VCE voltage limit table +typedef struct { + UCHAR numEntries; ///< Number of entries + ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_RECORD entries[1]; ///< Voltage limit state array +} ATOM_PPLIB_VCE_CLOCK_VOLTAGE_LIMIT_TABLE; + +/// VCE state record +typedef struct { + UCHAR ucVCEClockInfoIndex; ///< Index of VCE clock state + UCHAR ucClockInfoIndex; +} ATOM_PPLIB_VCE_STATE_RECORD; + +/// VCE state table +typedef struct { + UCHAR numEntries; ///< Number of state entries + ATOM_PPLIB_VCE_STATE_RECORD entries[1]; ///< State entries +} ATOM_PPLIB_VCE_STATE_TABLE; + +/// Extended header +typedef struct { + USHORT usSize; ///< size of header + ULONG rsv15; ///< reserved + ULONG rsv16; ///< reserved + USHORT usVCETableOffset; ///< offset of ATOM_PPLIB_VCE_TABLE + USHORT usUVDTableOffset; ///< offset of ATOM_PPLIB_UVD_TABLE + USHORT usSAMUTableOffset; ///< offset of ATOM_PPLIB_SAMU_TABLE + USHORT usPPMTableOffset; ///< offset of ATOM_PPLIB_PPM_TABLE + USHORT usACPTableOffset; ///< offset of ATOM_PPLIB_ACP_TABLE + USHORT usCACTDPTableOffset; ///< offset of ATOM_PPLIB_CACTDP_TABLE +} ATOM_PPLIB_EXTENDEDHEADER; + +/// VCE table +typedef struct { + UCHAR revid; ///< revision ID +} ATOM_PPLIB_VCE_TABLE; + + +typedef struct { + USHORT GfxPwrPlayTable261_STRUCT_fld0; + UCHAR GfxPwrPlayTable261_STRUCT_fld1; + USHORT GfxPwrPlayTable261_STRUCT_fld2; + UCHAR GfxPwrPlayTable261_STRUCT_fld3; +} GfxPwrPlayTable261_STRUCT; + +/// UVD clock info array +typedef struct { + UCHAR ucNumEntries; + GfxPwrPlayTable261_STRUCT entries[1]; +} GfxPwrPlayTable267_STRUCT; + +/// VCE voltage limit record +typedef struct { + USHORT usVoltage; ///< Voltage index + UCHAR ucUVDClockInfoIndex; ///< Index of VCE clock state +} ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD; + +/// VCE voltage limit table +typedef struct { + UCHAR numEntries; ///< Number of entries + ATOM_PPLIB_UVD_CLK_VOLT_LIMIT_RECORD entries[1]; ///< Voltage limit state array +} UVD_CLK_VOLT_LIMIT_TABLE; + +/// UVD table +typedef struct { + UCHAR revid; ///< revision ID +} ATOM_PPLIB_UVD_TABLE; + +/// SAMU voltage limit record +typedef struct { + USHORT usVoltage; ///< voltage + USHORT usSAMClockLow; ///< SamClk low + UCHAR usSAMClockHigh; ///< SamClk high +} ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD; + +/// SAMU voltage limit table +typedef struct { + UCHAR numEntries; ///< number of entries + ATOM_PPLIB_SAMCLK_VOLT_LIMIT_RECORD entries[1]; ///< array of entries +} ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE; + +/// SAMU table +typedef struct { + UCHAR revid; ///< table revision id +// ATOM_PPLIB_SAMCLK_VOLT_LIMIT_TABLE limits; ///< offset of table +} ATOM_PPLIB_SAMU_TABLE; + +typedef struct { + USHORT GfxPwrPlayTable310_fld0; + UCHAR GfxPwrPlayTable310_fld1; + USHORT GfxPwrPlayTable310_fld2; +} GfxPwrPlayTable310_STRUCT; + +typedef struct { + UCHAR numEntries; + GfxPwrPlayTable310_STRUCT entries[1]; +} GfxPwrPlayTable316_STRUCT; + +#define ATOM_PPM_A_A 1 +#define ATOM_PPM_A_I 2 + +/// Power Play table +typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 { + ATOM_COMMON_TABLE_HEADER sHeader; ///< Common header + UCHAR ucDataRevision; ///< Revision of PP table + UCHAR Reserved1[4]; ///< Reserved + USHORT usStateArrayOffset; ///< Offset from start of this table to array of ucNumStates ATOM_PPLIB_STATE structures + USHORT usClockInfoArrayOffset; ///< Offset from start of the table to ClockInfoArray + USHORT usNonClockInfoArrayOffset; ///< Offset from Start of the table to NonClockInfoArray + USHORT Reserved2[2]; ///< Reserved + USHORT usTableSize; ///< the size of this structure, or the extended structure + ULONG ulPlatformCaps; ///< See ATOM_PPLIB_CAPS_* + ATOM_PPLIB_THERMALCONTROLLER sThermalController; ///< Thermal controller stub. + USHORT Reserved4[2]; ///< Reserved + UCHAR Reserved5; ///< Reserved + USHORT Reserved6; ///< Reserved + USHORT usFormatID; ///< Format ID + USHORT Reserved7[1]; ///< Reserved + USHORT usExtendendedHeaderOffset; ///< Extended header offset + ULONG Reserved8[2]; ///< Reserved + USHORT ATOM_PPLIB_POWERPLAYTABLE4_fld17; + USHORT Reserved9[5]; ///< Reserved +} ATOM_PPLIB_POWERPLAYTABLE4; + +#pragma pack (pop) + + +AGESA_STATUS +GfxPwrPlayBuildTable ( + OUT VOID *Buffer, + IN GFX_PLATFORM_CONFIG *Gfx + ); + + +#endif |