/* $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"); }