diff options
Diffstat (limited to 'src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c')
-rwxr-xr-x | src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c | 269 |
1 files changed, 269 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c new file mode 100755 index 0000000000..f39655d701 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/Tech/DDR3/mrtspd3.c @@ -0,0 +1,269 @@ +/** + * @file + * + * mrtspd3.c + * + * Technology SPD supporting functions for DDR3 Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 44323 $ @e \$Date: 2010-12-22 01:24:58 -0700 (Wed, 22 Dec 2010) $ + * + **/ +/***************************************************************************** +* +* Copyright (c) 2011, 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. +* +* *************************************************************************** +* +*/ + +/* + *---------------------------------------------------------------------------- + * MODULES USED + * + *---------------------------------------------------------------------------- + */ + + + +#include "AGESA.h" +#include "amdlib.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mrtspd3.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_TECH_DDR3_MRTSPD3_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define _UNDEF_ 0xFF +#define MAX_DIES_PER_SOCKET 2 ///< Set to largest of any CPU + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the DRAM mode + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that the DRAM mode is set to DDR2 + */ + +BOOLEAN +MemRecTSetDramMode3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFLegacyBiosMode, 0); + TechPtr->NBPtr->SetBitField (TechPtr->NBPtr, BFDdr3Mode, 1); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function determines if DIMMs are present. It checks checksum and interrogates the SPDs + * + * @param[in,out] *TechPtr - Pointer to the MEM_TECH_BLOCK + * + * @return TRUE - indicates that a FATAL error has not occurred + * @return FALL - indicates that a FATAL error has not occurred + */ + +BOOLEAN +MemRecTDIMMPresence3 ( + IN OUT MEM_TECH_BLOCK *TechPtr + ) +{ + UINT8 Node; + UINT8 Dct; + UINT8 Channel; + UINT8 i; + SPD_DEF_STRUCT *SPDPtr; + UINT8 *SpdBufferPtr; + DIE_STRUCT *MCTPtr; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + MEM_NB_BLOCK *NBPtr; + UINT16 MaxDimms; + UINT16 Value16; + UINT8 Devwidth; + UINT8 Value8; + UINT16 DimmMask; + + NBPtr = TechPtr->NBPtr; + MCTPtr = NBPtr->MCTPtr; + + NBPtr->DimmToBeUsed = _UNDEF_; + for (Node = 0; Node < MAX_DIES_PER_SOCKET; Node++) { + NBPtr->SwitchNodeRec (NBPtr, Node); + for (Dct = 0; Dct < NBPtr->MCTPtr->DctCount; Dct++) { + NBPtr->SwitchDCT (NBPtr, Dct); + DCTPtr = NBPtr->DCTPtr; + for (Channel = 0; Channel < DCTPtr->ChannelCount; Channel++) { + NBPtr->SwitchChannel (NBPtr, Channel); + ChannelPtr = NBPtr->ChannelPtr; + SPDPtr = NBPtr->SPDPtr; + + // Get the maximum number of DIMMs + MaxDimms = MAX_DIMMS_PER_CHANNEL; + for (i = 0; i < MaxDimms; i++) { + // Bitmask representing dimm #i. + DimmMask = (UINT16) 1 << i; + + if (SPDPtr[i].DimmPresent) { + SpdBufferPtr = (UINT8 *)&(SPDPtr[i].Data); + + MCTPtr->DimmPresent |= DimmMask; + if (SpdBufferPtr[SPD_TYPE] == JED_DDR3SDRAM) { + ChannelPtr->ChDimmValid |= DimmMask; + if (NBPtr->DimmToBeUsed == _UNDEF_) { + NBPtr->DimmToBeUsed = i; + } + } + + // Check module type information. + if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_RDIMM || SpdBufferPtr[SPD_DIMM_TYPE] == JED_MINIRDIMM) { + ChannelPtr->RegDimmPresent |= DimmMask; + } + + if (SpdBufferPtr[SPD_DIMM_TYPE] == JED_SODIMM) { + ChannelPtr->SODimmPresent |= DimmMask; + } + + // Get the Dimm width data + Devwidth = SpdBufferPtr[SPD_DEV_WIDTH] & 0x7; + switch (Devwidth) { + case 0: + ChannelPtr->Dimmx4Present |= DimmMask; + Devwidth = 4; + break; + case 1: + ChannelPtr->Dimmx8Present |= DimmMask; + Devwidth = 8; + break; + case 2: + ChannelPtr->Dimmx16Present |= DimmMask; + Devwidth = 16; + break; + default: + IDS_ERROR_TRAP; + } + + // Determine the page size. + // page_size = 2^COLBITS * Devwidth/8 + // + Value16 = (((UINT16) 1 << (SpdBufferPtr[SPD_COL_SZ]&7)) * Devwidth) / 8; + if ((Value16 >> 11) == 0) { + DCTPtr->Timings.DIMM1KPage |= DimmMask; + } + + // Calculate bus loading per Channel + if (Devwidth == 16) { + Devwidth = 4; + } else if (Devwidth == 4) { + Devwidth = 16; + } + + // specify the number of ranks + Value8 = ((SpdBufferPtr[SPD_RANKS] >> 3) & 0x07) + 1; + if (Value8 > 2) { + ChannelPtr->DimmQrPresent |= DimmMask; + Devwidth = Devwidth << 2; + } else if (Value8 == 2) { + ChannelPtr->DimmDrPresent |= DimmMask; // Dual rank dimms + Devwidth = Devwidth << 1; + } + + ChannelPtr->Ranks = ChannelPtr->Ranks + Value8; + ChannelPtr->Loads = ChannelPtr->Loads + Devwidth; + ChannelPtr->Dimms++; + + // Check address mirror support for Unbuffered Dimms only + if ((ChannelPtr->RegDimmPresent & DimmMask) == 0) { + if ((SpdBufferPtr[SPD_ADDRMAP] & 1) != 0) { + ChannelPtr->DimmMirrorPresent |= DimmMask; + } + } + + // Get control word values for RC3, RC4 and RC5 + ChannelPtr->CtrlWrd03[i] = SpdBufferPtr[SPD_CTLWRD03] >> 4; + ChannelPtr->CtrlWrd04[i] = SpdBufferPtr[SPD_CTLWRD04] & 0x0F; + ChannelPtr->CtrlWrd05[i] = SpdBufferPtr[SPD_CTLWRD05] >> 4; + } // if DIMM present + } // Dimm loop + + if (ChannelPtr->ChDimmValid != 0) { + // exit loops + Channel = DCTPtr->ChannelCount; + Dct = NBPtr->MCTPtr->DctCount; + Node = MAX_DIES_PER_SOCKET; + } + } // Channel loop + } // DCT loop + } + + // If we have DIMMs, some further general characteristics checking + if (NBPtr->DimmToBeUsed == _UNDEF_) { + // Leave with an error - no dimms on this DCT + // LibAmdEventLog (AGESA_FATAL, MEM_ERROR_NO_DIMM_FOUND, 0, NBPtr->Dct, NBPtr->Channel, 0); //@attention commented out since it is not defined in recovery code + SetMemRecError (AGESA_FATAL, MCTPtr); + } + + return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ |