aboutsummaryrefslogtreecommitdiff
path: root/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c')
-rw-r--r--src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c526
1 files changed, 526 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c
new file mode 100644
index 0000000000..c81fd5ee3f
--- /dev/null
+++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbInitKB/GfxIntegratedInfoTableKB.c
@@ -0,0 +1,526 @@
+/* $NoKeywords:$ */
+/**
+ * @file
+ *
+ * Integrated table info init
+ *
+ *
+ *
+ * @xrefitem bom "File Content Label" "Release Content"
+ * @e project: AGESA
+ * @e sub-project: GNB
+ * @e \$Revision: 87902 $ @e \$Date: 2013-02-12 15:59:48 -0600 (Tue, 12 Feb 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 "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 "GnbRegistersKB.h"
+#include "GnbRegisterAccKB.h"
+#include "GnbNbInitLibV1.h"
+#include "GfxConfigLib.h"
+#include "GfxIntegratedInfoTable.h"
+#include "GfxPwrPlayTable.h"
+#include "GfxLibKB.h"
+#include "GfxLibV3.h"
+#include "OptionGnb.h"
+#include "Filecode.h"
+#define FILECODE PROC_GNB_MODULES_GNBINITKB_GFXINTEGRATEDINFOTABLEKB_FILECODE
+/*----------------------------------------------------------------------------------------
+ * D E F I N I T I O N S A N D M A C R O S
+ *----------------------------------------------------------------------------------------
+ */
+
+#define GFX_REFCLK 100 // (in MHz) Reference clock is 100 MHz
+
+/*----------------------------------------------------------------------------------------
+ * 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
+ *----------------------------------------------------------------------------------------
+ */
+AGESA_STATUS
+GfxMapEngineToDisplayPathKB (
+ IN PCIe_ENGINE_CONFIG *Engine,
+ OUT EXT_DISPLAY_PATH *DisplayPathList,
+ IN GFX_PLATFORM_CONFIG *Gfx
+ );
+
+AGESA_STATUS
+GfxIntInfoTableInterfaceKB (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ );
+
+CONST UINT8 DdiLaneConfigArrayKB [][4] = {
+ {8, 11, 0, 0},
+ {12, 15, 1, 1},
+ {11, 8, 0, 0},
+ {15, 12, 1, 1},
+ {16, 19, 6, 6},
+ {19, 16, 6, 6}
+};
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Initialize display path for given engine
+ *
+ *
+ *
+ * @param[in] Engine Engine configuration info
+ * @param[out] DisplayPathList Display path list
+ * @param[in] Gfx Pointer to global GFX configuration
+ */
+
+AGESA_STATUS
+GfxMapEngineToDisplayPathKB (
+ IN PCIe_ENGINE_CONFIG *Engine,
+ OUT EXT_DISPLAY_PATH *DisplayPathList,
+ IN GFX_PLATFORM_CONFIG *Gfx
+ )
+{
+ AGESA_STATUS Status;
+ UINT8 PrimaryDisplayPathId;
+ UINT8 SecondaryDisplayPathId;
+ UINTN DisplayPathIndex;
+ PrimaryDisplayPathId = 0xff;
+ SecondaryDisplayPathId = 0xff;
+ for (DisplayPathIndex = 0; DisplayPathIndex < (sizeof (DdiLaneConfigArrayKB) / 4); DisplayPathIndex++) {
+ if (DdiLaneConfigArrayKB[DisplayPathIndex][0] == Engine->EngineData.StartLane &&
+ DdiLaneConfigArrayKB[DisplayPathIndex][1] == Engine->EngineData.EndLane) {
+ PrimaryDisplayPathId = DdiLaneConfigArrayKB[DisplayPathIndex][2];
+ SecondaryDisplayPathId = DdiLaneConfigArrayKB[DisplayPathIndex][3];
+ break;
+ }
+ }
+
+ if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeDualLinkDVI ||
+ (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeLvds && PrimaryDisplayPathId != 0)) {
+ // Display config invalid for KB
+ PrimaryDisplayPathId = 0xff;
+ }
+
+ if (PrimaryDisplayPathId != 0xff) {
+ ASSERT (Engine->Type.Ddi.DdiData.AuxIndex <= Aux3);
+ IDS_HDT_CONSOLE (GFX_MISC, " Allocate Display Connector at Primary sPath[%d]\n", PrimaryDisplayPathId);
+ Engine->InitStatus |= INIT_STATUS_DDI_ACTIVE;
+ GfxIntegratedCopyDisplayInfo (
+ Engine,
+ &DisplayPathList[PrimaryDisplayPathId],
+ (PrimaryDisplayPathId != SecondaryDisplayPathId) ? &DisplayPathList[SecondaryDisplayPathId] : NULL,
+ Gfx
+ );
+
+ if (Engine->Type.Ddi.DdiData.ConnectorType == ConnectorTypeSingleLinkDviI) {
+ LibAmdMemCopy (&DisplayPathList[6], &DisplayPathList[PrimaryDisplayPathId], sizeof (EXT_DISPLAY_PATH), GnbLibGetHeader (Gfx));
+ DisplayPathList[6].usDeviceACPIEnum = 0x100;
+ DisplayPathList[6].usDeviceTag = ATOM_DEVICE_CRT1_SUPPORT;
+ }
+
+ Status = AGESA_SUCCESS;
+ } else {
+ IDS_HDT_CONSOLE (GFX_MISC, " Error!!! Map DDI lanes %d - %d to display path failed\n",
+ Engine->EngineData.StartLane,
+ Engine->EngineData.EndLane
+ );
+ PutEventLog (
+ AGESA_ERROR,
+ GNB_EVENT_INVALID_DDI_LINK_CONFIGURATION,
+ Engine->EngineData.StartLane,
+ Engine->EngineData.EndLane,
+ 0,
+ 0,
+ GnbLibGetHeader (Gfx)
+ );
+ Status = AGESA_ERROR;
+ }
+ return Status;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ *Init KB Nb p-State MemclkFreq
+ *
+ *
+ * @param[in] IntegratedInfoTable Integrated info table pointer
+ * @param[in] Gfx Gfx configuration info
+ */
+
+STATIC VOID
+GfxFillNbPstateMemclkFreqKB (
+ IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
+ IN GFX_PLATFORM_CONFIG *Gfx
+ )
+{
+ D18F2x94_dct0_STRUCT D18F2x94;
+ D18F2x2E0_dct0_STRUCT D18F2x2E0;
+ D18F5x160_STRUCT NbPstate;
+ UINT8 i;
+ ULONG memps0_freq;
+ ULONG memps1_freq;
+ UINT8 last_valid_pstate;
+ GNB_HANDLE *GnbHandle;
+
+ GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx));
+ ASSERT (GnbHandle != NULL);
+
+ GnbRegisterReadKB (
+ GnbHandle,
+ D18F2x94_dct0_TYPE,
+ D18F2x94_dct0_ADDRESS,
+ &D18F2x94.Value,
+ 0,
+ GnbLibGetHeader (Gfx)
+ );
+
+ GnbRegisterReadKB (
+ GnbHandle,
+ D18F2x2E0_dct0_TYPE,
+ D18F2x2E0_dct0_ADDRESS,
+ &D18F2x2E0.Value,
+ 0,
+ GnbLibGetHeader (Gfx)
+ );
+
+ memps0_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) D18F2x94.Field.MemClkFreq, GnbLibGetHeader (Gfx));
+ memps1_freq = 100 * GfxLibExtractDramFrequencyV3 ((UINT8) D18F2x2E0.Field.M1MemClkFreq, GnbLibGetHeader (Gfx));
+
+ last_valid_pstate = 0;
+ for (i = 0; i < 4; i++) {
+ NbPstate.Value = 0;
+ GnbRegisterReadKB (
+ GnbHandle,
+ TYPE_D18F5,
+ (D18F5x160_ADDRESS + (i * 4)),
+ &NbPstate.Value,
+ 0,
+ GnbLibGetHeader (Gfx)
+ );
+ if (NbPstate.Field.NbPstateEn == 1) {
+ last_valid_pstate = i;
+ IntegratedInfoTable->ulNbpStateMemclkFreq[i] = (NbPstate.Field.MemPstate == 0) ? memps0_freq : memps1_freq;
+ } else {
+ IntegratedInfoTable->ulNbpStateMemclkFreq[i] =
+ IntegratedInfoTable->ulNbpStateMemclkFreq[last_valid_pstate];
+ }
+ }
+
+ for (i = 0; i < 4; i++) {
+ IDS_HDT_CONSOLE (GNB_TRACE, " Nclk[%d] = %08x\n", i, IntegratedInfoTable->ulNbpStateNClkFreq[i]);
+ IDS_HDT_CONSOLE (GNB_TRACE, " Mclk[%d] = %08x\n", i, IntegratedInfoTable->ulNbpStateMemclkFreq[i]);
+ }
+
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ *Calculate ulGMCRestoreResetTime
+ *
+ *
+ * @param[in] IntegratedInfoTable Integrated info table pointer
+ * @param[in] Gfx Gfx configuration info
+ * @param[in] PpF1Array
+ * @retval AGESA_STATUS
+ */
+///@todo - this is currently based on TN
+STATIC AGESA_STATUS
+GfxCalculateRestoreResetTimeKB (
+ IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
+ IN GFX_PLATFORM_CONFIG *Gfx,
+ IN PP_F1_ARRAY_V2 *PpF1Array
+ )
+{
+ UINT8 MaxDid;
+ ULONG FreqSclk;
+ UINTN Index;
+ UINT32 TSclk;
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeKB Enter\n");
+ MaxDid = PpF1Array->PP_FUSE_ARRAY_V2_fld3;
+ for (Index = 0; Index < 4; Index++) {
+ MaxDid = MAX (MaxDid, PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index]);
+ }
+ IDS_HDT_CONSOLE (GNB_TRACE, "MaxDid = %d\n", MaxDid);
+ FreqSclk = GfxFmCalculateClock (MaxDid, GnbLibGetHeader (Gfx));
+ // FreqSclk is in 10KHz units - need calculations in nS
+ // For accuracy, do calculations in .01nS, then convert at the end
+ TSclk = (100 * (1000000000 / 10000)) / FreqSclk;
+
+ IntegratedInfoTable->ulGMCRestoreResetTime = ((TSclk * 662) + 99) / 100;
+ IDS_HDT_CONSOLE (GNB_TRACE, "ulGMCRestoreResetTime = %d\n", IntegratedInfoTable->ulGMCRestoreResetTime);
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxCalculateRestoreResetTimeKB Exit\n");
+
+ return AGESA_SUCCESS;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ *Init KB HTC Data
+ *
+ *
+ * @param[in] IntegratedInfoTable Integrated info table pointer
+ * @param[in] Gfx Gfx configuration info
+ */
+
+STATIC VOID
+GfxFillHtcDataKB (
+ IN OUT ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
+ IN GFX_PLATFORM_CONFIG *Gfx
+ )
+{
+ D18F3x64_STRUCT D18F3x64;
+ GNB_HANDLE *GnbHandle;
+
+ GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx));
+ ASSERT (GnbHandle != NULL);
+
+ GnbRegisterReadKB (
+ GnbHandle,
+ D18F3x64_TYPE,
+ D18F3x64_ADDRESS,
+ &D18F3x64.Value,
+ 0,
+ GnbLibGetHeader (Gfx)
+ );
+
+ if (D18F3x64.Field.HtcEn == 1) {
+ IntegratedInfoTable->ucHtcTmpLmt = (UCHAR) (D18F3x64.Field.HtcTmpLmt / 2 + 52);
+ IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = (UCHAR) (D18F3x64.Field.HtcHystLmt / 2);
+ } else {
+ IntegratedInfoTable->ucHtcTmpLmt = 0;
+ IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8_fld11 = 0;
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ *Init Sclk <-> VID table
+ *
+ *
+ * @param[in] PpF1Array
+ * @param[in] IntegratedInfoTable Integrated info table pointer
+ * @param[in] Gfx Gfx configuration info
+ */
+
+STATIC VOID
+GfxIntInfoTableInitSclkTableKB (
+ IN PP_F1_ARRAY_V2 *PpF1Array,
+ IN ATOM_INTEGRATED_SYSTEM_INFO_V1_8 *IntegratedInfoTable,
+ IN GFX_PLATFORM_CONFIG *Gfx
+ )
+{
+ UINT8 Index;
+ UINTN AvailSclkIndex;
+ GnbGfx275_STRUCT *AvailSclkList;
+ BOOLEAN Sorting;
+ AvailSclkList = &IntegratedInfoTable->ATOM_INTEGRATED_SYSTEM_INFO_V1_8[0];
+
+ AvailSclkIndex = 0;
+ for (Index = 0; Index < 5; Index++) {
+ if (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index] != 0) {
+ AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld0 = GfxFmCalculateClock (PpF1Array->PP_FUSE_ARRAY_V2_fld33[Index], GnbLibGetHeader (Gfx));
+ AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld1 = Index;
+ AvailSclkList[AvailSclkIndex].GnbGfx275_STRUCT_fld2 = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index];
+ AvailSclkIndex++;
+ }
+ }
+ //Sort by VoltageIndex & GnbGfx275_STRUCT_fld0
+ if (AvailSclkIndex > 1) {
+ do {
+ Sorting = FALSE;
+ for (Index = 0; Index < (AvailSclkIndex - 1); Index++) {
+ GnbGfx275_STRUCT Temp;
+ BOOLEAN Exchange;
+ Exchange = FALSE;
+ if (AvailSclkList[Index].GnbGfx275_STRUCT_fld1 > AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld1) {
+ Exchange = TRUE;
+ }
+ if ((AvailSclkList[Index].GnbGfx275_STRUCT_fld1 == AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld1) &&
+ (AvailSclkList[Index].GnbGfx275_STRUCT_fld0 > AvailSclkList[Index + 1].GnbGfx275_STRUCT_fld0)) {
+ Exchange = TRUE;
+ }
+ if (Exchange) {
+ Sorting = TRUE;
+ LibAmdMemCopy (&Temp, &AvailSclkList[Index], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx));
+ LibAmdMemCopy (&AvailSclkList[Index], &AvailSclkList[Index + 1], sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx));
+ LibAmdMemCopy (&AvailSclkList[Index + 1], &Temp, sizeof (GnbGfx275_STRUCT), GnbLibGetHeader (Gfx));
+ }
+ }
+ } while (Sorting);
+ }
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Build integrated info table
+ *
+ *
+ *
+ * @param[in] Gfx Gfx configuration info
+ * @retval AGESA_STATUS
+ */
+AGESA_STATUS
+STATIC
+GfxIntInfoTableInitKB (
+ IN GFX_PLATFORM_CONFIG *Gfx
+ )
+{
+ AGESA_STATUS Status;
+ AGESA_STATUS AgesaStatus;
+ ATOM_FUSION_SYSTEM_INFO_V3 SystemInfoTableV3;
+ PP_F1_ARRAY_V2 *PpF1Array;
+ ATOM_PPLIB_POWERPLAYTABLE4 *PpTable;
+ D18F5x170_STRUCT D18F5x170;
+ GNB_HANDLE *GnbHandle;
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInitKB Enter\n");
+
+ AgesaStatus = AGESA_SUCCESS;
+ GnbHandle = GnbGetHandle (GnbLibGetHeader (Gfx));
+ ASSERT (GnbHandle != NULL);
+ PpF1Array = GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, GnbLibGetHeader (Gfx));
+ if (PpF1Array != NULL) {
+ LibAmdMemFill (&SystemInfoTableV3, 0x00, sizeof (ATOM_FUSION_SYSTEM_INFO_V3), GnbLibGetHeader (Gfx));
+
+ // Use common initialization first
+ Status = GfxIntInfoTableInitV3 (Gfx, &SystemInfoTableV3, PpF1Array);
+ // Complete table with KB-specific fields
+
+ // Build PP table
+ PpTable = (ATOM_PPLIB_POWERPLAYTABLE4*) &SystemInfoTableV3.ulPowerplayTable;
+ Status = GfxPwrPlayBuildTable (PpTable, Gfx);
+ AGESA_STATUS_UPDATE (Status, AgesaStatus);
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "KB Pplay done\n");
+
+ // Assign usFormatID to 0x0013 to represent Kabini
+ PpTable->usFormatID = 0x13;
+
+ // Build Sclk info table
+ GfxIntInfoTableInitSclkTableKB (PpF1Array, &SystemInfoTableV3.sIntegratedSysInfo, Gfx);
+
+ // Fill in Nb P-state MemclkFreq Data
+ GfxFillNbPstateMemclkFreqKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx);
+ // Fill in HTC Data
+ GfxFillHtcDataKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx);
+
+ // Family specific data update
+ // Determine ulGMCRestoreResetTime
+ Status = GfxCalculateRestoreResetTimeKB (&SystemInfoTableV3.sIntegratedSysInfo, Gfx, PpF1Array);
+ AGESA_STATUS_UPDATE (Status, AgesaStatus);
+
+ //GfxFmIntegratedInfoTableInit (&SystemInfoV1Table.sIntegratedSysInfo, Gfx);
+ SystemInfoTableV3.sIntegratedSysInfo.ulDDR_DLL_PowerUpTime = 4940;
+ SystemInfoTableV3.sIntegratedSysInfo.ulDDR_PLL_PowerUpTime = 2000;
+
+ SystemInfoTableV3.sIntegratedSysInfo.ulGPUCapInfo =
+ GPUCAPINFO_TMDS_HDMI_USE_SINGLE_PLL_MODE |
+ GPUCAPINFO_DP_USE_SINGLE_PLL_MODE |
+ GPUCAPINFO_DFS_BYPASS_DISABLE;
+
+ // GPUCAPINFO_DFS_BYPASS_ENABLE should be enabled by default for MOBILE systems
+ if ((Gfx->AmdPlatformType & AMD_PLATFORM_MOBILE) != 0) {
+ SystemInfoTableV3.sIntegratedSysInfo.ulGPUCapInfo |= GPUCAPINFO_DFS_BYPASS_ENABLE;
+ }
+
+ // Check if NbPstate enable
+ GnbRegisterReadKB (GnbHandle, TYPE_D18F5, D18F5x170_ADDRESS, &D18F5x170.Value, 0, GnbLibGetHeader (Gfx));
+ if ((D18F5x170.Field.SwNbPstateLoDis != 1) && (D18F5x170.Field.NbPstateMaxVal != 0)) {
+ // If NbPstate enable, then enable NBDPM for driver
+ SystemInfoTableV3.sIntegratedSysInfo.ulSystemConfig |= BIT3;
+ }
+
+ IDS_OPTION_CALLOUT (IDS_CALLOUT_GNB_INTEGRATED_TABLE_CONFIG, &SystemInfoTableV3.sIntegratedSysInfo, GnbLibGetHeader (Gfx));
+ //Copy integrated info table to Frame Buffer. (Do not use LibAmdMemCopy, routine not guaranteed access to above 4G memory in 32 bit mode.)
+ GfxIntInfoTablePostToFbV3 (&SystemInfoTableV3, Gfx);
+
+ GNB_DEBUG_CODE (
+ GfxIntInfoTableDebugDumpV3 (&SystemInfoTableV3, Gfx);
+ );
+ } else {
+ Status = AGESA_ERROR;
+ AGESA_STATUS_UPDATE (Status, AgesaStatus);
+ }
+
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInitKB Exit [0x%x]\n", Status);
+ return AgesaStatus;
+}
+
+/*----------------------------------------------------------------------------------------*/
+/**
+ * Build integrated info table
+ * GMC FB access requred
+ *
+ *
+ * @param[in] StdHeader Standard configuration header
+ * @retval AGESA_STATUS
+ */
+AGESA_STATUS
+GfxIntInfoTableInterfaceKB (
+ IN AMD_CONFIG_PARAMS *StdHeader
+ )
+{
+ AGESA_STATUS AgesaStatus;
+ AGESA_STATUS Status;
+ GFX_PLATFORM_CONFIG *Gfx;
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInterfaceKB Enter\n");
+ AgesaStatus = AGESA_SUCCESS;
+ if (GfxLibIsControllerPresent (StdHeader)) {
+ Status = GfxLocateConfigData (StdHeader, &Gfx);
+ AGESA_STATUS_UPDATE (Status, AgesaStatus);
+ if (Status != AGESA_FATAL) {
+ Status = GfxIntInfoTableInitKB (Gfx);
+ AGESA_STATUS_UPDATE (Status, AgesaStatus);
+ }
+ }
+ IDS_HDT_CONSOLE (GNB_TRACE, "GfxIntInfoTableInterfaceKB Exit[0x%x]\n", AgesaStatus);
+ return AgesaStatus;
+}