diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c')
-rw-r--r-- | src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c | 348 |
1 files changed, 348 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c new file mode 100644 index 0000000000..516739aa3c --- /dev/null +++ b/src/vendorcode/amd/agesa/f16kb/Proc/GNB/Modules/GnbNbInitLibV5/GnbNbInitLibV5.c @@ -0,0 +1,348 @@ +/* $NoKeywords:$ */ +/** + * @file + * + * NB services + * + * + * + * @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 "Ids.h" +#include "amdlib.h" +#include "heapManager.h" +#include "Gnb.h" +#include "GnbPcieConfig.h" +#include "GnbCommonLib.h" +#include "Filecode.h" +#include "GnbRegistersCommonV2.h" +#include "GnbF1Table.h" +#define FILECODE PROC_GNB_MODULES_GNBNBINITLIBV5_GNBNBINITLIBV5_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 + *---------------------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------------------- + * 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 +GnbSetTomV5 ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +UINT8 +GnbLocateLowestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT32 +GnbTranslateVidCodeToMillivoltV5 ( + IN UINT8 Vid, + IN AMD_CONFIG_PARAMS *StdHeader + ); + +UINT8 +GnbLocateHighestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ); +/*----------------------------------------------------------------------------------------*/ +/** + * Init NB set top of memory + * + * + * + * @param[in] NbPciAddress Gnb PCI address + * @param[in] StdHeader Standard Configuration Header + */ + +AGESA_STATUS +GnbSetTomV5 ( + IN PCI_ADDR NbPciAddress, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + AGESA_STATUS Status; + UINT64 MsrData; + UINT64 GnbTom2; + UINT64 GnbTom3; + UINT32 Value; + + Status = AGESA_SUCCESS; + //Read memory size below 4G from MSR C001_001A + LibAmdMsrRead (TOP_MEM, &MsrData, StdHeader); + //Write to NB register 0x90 + Value = (UINT32)MsrData & 0xFF800000; //Keep bits 31:23 + GnbLibPciRMW ( + NbPciAddress.AddressValue | D0F0x90_ADDRESS, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + if (Value == 0) { + Status = AGESA_WARNING; + } + + GnbTom2 = 0; + GnbTom3 = 0; + LibAmdMsrRead (SYS_CFG, &MsrData, StdHeader); + if ((MsrData & BIT21) != 0) { + //If SYS_CFG(MtrrTom2En) then configure GNB TOM2 and TOM3 + //Read memory size above 4G from TOP_MEM2 (MSR C001_001D) + LibAmdMsrRead (TOP_MEM2, &MsrData, StdHeader); + if ((MsrData & (UINT64)0x0000FFFFFFC00000) > ((UINT64)0x0000010000000000)) { + // If TOP_MEM2 is above 1TB, enable GNB TOM2 and TOM3 + // Set TOM2 for below 1TB limit + GnbTom2 = 0x000000FD00000000; + // TOM3 is INCLUSIVE, so set it to TOM - 1 using bits 47:22 + GnbTom3 = (MsrData - 1) & (UINT64)0x0000FFFFFFC00000; + } else { + // If TOP_MEM2 is below 1TB, set TOM2 using bits 39:22 + GnbTom2 = MsrData & (UINT64)0x000000FFFFC00000; //Keep bits 39:22 + // If TOP_MEM2 is below 1TB, disable GNB TOM3 + GnbTom3 = 0; + } + } + + if (GnbTom2 != 0) { + // Write memory size[39:32] to indirect register 1A[7:0] + Value = (UINT32) ((GnbTom2 >> 32) & 0xFF); + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x1A_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0xFFFFFF00, + Value, + StdHeader + ); + // Write memory size[31:23] to indirect register 19[31:23] and enable memory through bit 0 + Value = (UINT32)GnbTom2 & 0xFF800000; //Keep bits 31:23 + Value |= BIT0; // Enable top of memory + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + D0F0x64_x19_ADDRESS | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0x007FFFFF, + Value, + StdHeader + ); + } + + if (GnbTom3 != 0) { + // Above 1TB addressing TOM3 if MSR TOM is above 1TB + // Write memory size[47:22] to indirect register 4E[25:0] and enable memory through bit 31 + Value = (UINT32) (GnbTom3 >> 22); + Value |= BIT31; + GnbLibPciIndirectRMW ( + NbPciAddress.AddressValue | D0F0x60_ADDRESS, + 0x4e | IOC_WRITE_ENABLE, + AccessS3SaveWidth32, + 0x83FFFFFF, + Value, + StdHeader + ); + } + return Status; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of highest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +UINT8 +GnbLocateHighestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVid; + UINT8 MaxVidIndex; + UINTN Index; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MaxVidIndex = 0; + MaxVid = 0xff; + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] != 0 && PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] < MaxVid) { + MaxVid = PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index]; + MaxVidIndex = (UINT8) Index; + } + } + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex] != 0); + return MaxVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the index of lowest SCLK VID + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID index + */ +STATIC UINT8 +GnbLocateLowestVidIndexV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + UINTN Index; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + if (PpF1Array == NULL) { + IDS_HDT_CONSOLE (GNB_TRACE, " ERROR!!! Heap Location\n"); + return 0; + } + + MinVidIndex = 0; + + for (Index = 0; Index < 5; Index++) { + if (PpF1Array->PP_FUSE_ARRAY_V2_fld32[Index] > PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex]) { + MinVidIndex = (UINT8) Index; + } + } + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + return MinVidIndex; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the highest SCLK VID (high voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateHighestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MaxVidIndex; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + + MaxVidIndex = GnbLocateHighestVidIndexV5 (StdHeader); + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex] != 0); + return PpF1Array->PP_FUSE_ARRAY_V2_fld32[MaxVidIndex]; + +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Get the lowest SCLK VID (low voltage) + * + * @param[in] StdHeader Standard configuration header + * @retval NBVDD VID + */ +UINT8 +GnbLocateLowestVidCodeV5 ( + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 MinVidIndex; + PP_F1_ARRAY_V2 *PpF1Array; + + PpF1Array = (PP_F1_ARRAY_V2 *) GnbLocateHeapBuffer (AMD_PP_F1_TABLE_HANDLE, StdHeader); + ASSERT (PpF1Array != NULL); + MinVidIndex = GnbLocateLowestVidIndexV5 (StdHeader); + ASSERT (PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex] != 0); + return PpF1Array->PP_FUSE_ARRAY_V2_fld32[MinVidIndex]; +} + +/*----------------------------------------------------------------------------------------*/ +/** + * Translate VID code to millivolt with two fraction bits + * + * + * @param[in] Vid VID code + * @param[in] StdHeader Standard configuration header + * @retval 100 millivolt with two fraction bits + */ + +UINT32 +GnbTranslateVidCodeToMillivoltV5 ( + IN UINT8 Vid, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT32 Millivolt; + + // According to SVI2 spec, Vid Code 0xF7 is 6.25mv. 6.25mv is one boundary value. + if (Vid > 0xF7) { + Vid = 0xF7; + ASSERT (FALSE); + } + + // Equation: VID code increase/decrease 1, there is one 6.25mv change. + // 6.25mv could be described using integer 625 with two fraction bits. + Millivolt = (0xF7 - Vid + 1) * 625; + + return Millivolt; +} |