summaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3
diff options
context:
space:
mode:
authorSiyuan Wang <wangsiyuanbuaa@gmail.com>2013-07-25 15:14:15 +0800
committerBruce Griffith <Bruce.Griffith@se-eng.com>2013-08-04 05:40:37 +0200
commitaffe85fbc8a13d35960aa92ae87cbb6330ad253f (patch)
tree9c1ace69f12b06b6544faf041994aa4288fb2e45 /src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3
parentae8d06969bdde9b1250bc3c4ad93f5db408dae98 (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')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.c504
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxIntegratedInfoTable.h73
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.c257
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxLibV3.h70
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.c1233
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbGfxIntTableV3/GfxPwrPlayTable.h321
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