diff options
author | efdesign98 <efdesign98@gmail.com> | 2011-07-13 16:43:39 -0700 |
---|---|---|
committer | Patrick Georgi <patrick@georgi-clan.de> | 2011-07-15 14:17:00 +0200 |
commit | 229f7cb6d660ad4063c9f65e3fabfff80583f281 (patch) | |
tree | eaa627ceb717250c38f1bc6ca79868b331d12e23 /src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB | |
parent | 25f23f17bcb2bac9fb5af0f5d6d1d8c1c9ea16ff (diff) | |
download | coreboot-229f7cb6d660ad4063c9f65e3fabfff80583f281.tar.xz |
Add the AMD Family10 Agesa code
This change officially adds the Agesa code for the AMD Family 10
cpus. This code supports the G34 and C32 sockets.
Change-Id: Idae50417e530ad40a29fb6fff5b427f6b138126c
Signed-off-by: Frank Vibrans <frank.vibrans@amd.com>
Signed-off-by: efdesign98 <efdesign98@gmail.com>
Reviewed-on: http://review.coreboot.org/95
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <patrick@georgi-clan.de>
Diffstat (limited to 'src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB')
21 files changed, 5823 insertions, 0 deletions
diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.c new file mode 100755 index 0000000000..ec7a1e107c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.c @@ -0,0 +1,700 @@ +/** + * @file + * + * mrnc32.c + * + * Common Northbridge functions for C32 Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 13435 $ @e \$Date: 2009-05-12 02:26:55 +0800 (Tue, 12 May 2009) $ + * + **/ +/***************************************************************************** +* +* 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 "mrport.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mm.h" +#include "mn.h" +#include "mrnc32.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNC32_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define MAX_DCTS_PER_DIE 2 +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemRecNInitNBRegTableC32 ( + IN OUT TSEFO *NBRegTable + ); + +UINT32 +STATIC +MemRecNCmnGetSetFieldC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ); + +BOOLEAN +STATIC +MemRecNIsIdSupportedC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +VOID +STATIC +MemRecNSwitchNodeC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] NodeID - Node ID for this NB block + * + * @return TRUE - This node is a C32 and this NB block has been initialized + * @return FALSE - This node is not a C32 + */ + +BOOLEAN +MemRecConstructNBBlockC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemRecNIsIdSupportedC32 (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + MCTPtr = &MemPtr->DiesPerSystem[NodeID]; + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_C32 * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_C32 * ( + sizeof (CH_DEF_STRUCT) + ( + MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES + ) + ) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_C32; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + MemPtr->DiesPerSystem[NodeID + 1].DctCount = MAX_DCTS_PER_NODE_C32; + MemPtr->DiesPerSystem[NodeID + 1].DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_C32 * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_C32; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_C32; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_C32 * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_C32; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + } + } + + // + // Initialize NB block's variables + // + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->MCTPtr = MCTPtr; + NBPtr->AllNodeMCTPtr = &MemPtr->DiesPerSystem[NodeID]; + NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + + NBPtr->DctCachePtr = NBPtr->DctCache; + + MemRecNInitNBRegTableC32 (NBPtr->NBRegTable); + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); + + NBPtr->InitRecovery = MemRecNMemInitNb; + + NBPtr->SwitchNodeRec = MemRecNSwitchNodeC32; + NBPtr->SwitchDCT = MemRecNSwitchDctC32; + NBPtr->SwitchChannel = MemRecNSwitchChannelC32; + NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb; + NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; + NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; + NBPtr->sendZQCmd = MemRecNSendZQCmdNb; + NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb; + + NBPtr->GetBitField = MemRecNGetBitFieldNb; + NBPtr->SetBitField = MemRecNSetBitFieldNb; + NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; + NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; + + NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldC32; + NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyC32; + NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctC32; + NBPtr->TrainingFlow = MemNRecTrainingFlowNb; + NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctC32; + NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE; + MemRecNSwitchDctC32 (NBPtr, 0); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the current die to work on. + * Should be called before accessing a certain die + * All data structures will be updated to point to the current node + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] NodeID - ID of the target die + * + */ + +VOID +STATIC +MemRecNSwitchNodeC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID + ) +{ + NBPtr->MCTPtr = &(NBPtr->AllNodeMCTPtr[NodeID]); + NBPtr->Node = NodeID; + NBPtr->MCTPtr->NodeId = NodeID; + MemRecNSwitchDctC32 (NBPtr, NBPtr->Dct); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemRecNSwitchDctC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + NBPtr->Dct = Dct & 1; + NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[(NBPtr->MCTPtr->NodeId * MAX_DCTS_PER_DIE + Dct) * MAX_DIMMS_PER_CHANNEL]); + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + + MemRecNSwitchChannelC32 (NBPtr, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemRecNSwitchChannelC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = 0; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[0]); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 index; + UINT16 offset; + UINT32 value; + UINT32 address; + UINT8 DIMM; + UINT8 Rank; + UINT8 Byte; + UINT8 Nibble; + + DIMM = DRBN_DIMM (DrbnVar); + Rank = DRBN_RANK (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + Nibble = DRBN_NBBL (DrbnVar); + + switch (TrnDly) { + case AccessRcvEnDly: + index = 0x10; + break; + case AccessWrDqsDly: + index = 0x30; + break; + case AccessWrDatDly: + index = 0x01; + break; + case AccessRdDqsDly: + index = 0x05; + break; + case AccessPhRecDly: + index = 0x50; + break; + default: + index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + index += (DIMM * 3); + if ((Byte & 0x04) != 0) { + // if byte 4,5,6,7 + index += 0x10; + } + if ((Byte & 0x02) != 0) { + // if byte 2,3,6,7 + index++; + } + if (Byte > 7) { + index += 2; + } + offset = 16 * (Byte % 2); + index |= (Rank << 8); + index |= (Nibble << 9); + break; + + case AccessRdDqsDly: + Field &= ~ 0x0001; + case AccessWrDatDly: + index += (DIMM * 0x100); + if (Nibble != 0) { + if (Rank != 0) { + index += 0xA0; + } else { + index += 0x70; + } + } else if (Rank != 0) { + index += 0x60; + } + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + index += (Byte / 4); + offset = 8 * (Byte % 4); + break; + default: + offset = 0; + IDS_ERROR_TRAP; + } + + address = index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + + if (IsSet != 0) { + if (TrnDly == AccessPhRecDly) { + value = NBPtr->DctCachePtr->PhRecReg[index & 0x03]; + } + + value = ((UINT32)Field << offset) | (value & (~((UINT32)0xFF << offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, value); + address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[index & 0x03] = value; + } + } else { + value = (value >> offset) & 0xFF; + } + + return value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Name of Field to be set + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNCmnGetSetFieldC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + SBDFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + + Value = 0; + if (FieldName < BFEndOfList) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address != 0) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = TSEFO_TYPE (Address); + + // If Fn2 and DCT1 selected, set Address to be 1xx + if (((Address & 0xF000) == 0x2000) && (NBPtr->Dct != 0)) { + Address |= 0x0100; + } + if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) { + // Special DCT Phy access + Address &= 0x0FFFFFFF; + Lowbit = 0; + Highbit = 16; + } else { + // Normal DCT Phy access + Address = TSEFO_OFFSET (Address); + } + + + if (Type == NB_ACCESS) { + // Address |= (((UINT32) (24 + 0)) << 15); + PciAddr.AddressValue = Address; + // Fix for MCM + PciAddr.Address.Device = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Device; + PciAddr.Address.Bus = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Bus; + PciAddr.Address.Segment = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Segment; + Address = PciAddr.AddressValue; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + } else { + IDS_ERROR_TRAP; + } + + if (IsSet != 0) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + } else { + IDS_ERROR_TRAP; + } + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + } + } + } else { + IDS_ERROR_TRAP; // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes bit field translation table + * +* @param[in,out] *NBRegTable - Pointer to the NB Table * + */ + +VOID +STATIC +MemRecNInitNBRegTableC32 ( + IN OUT TSEFO *NBRegTable + ) +{ + UINT16 i; + for (i = 0; i <= BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 31, 0, BFMctCfgHiReg); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp); + +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemRecNIsIdSupportedC32 + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + * @return TRUE - This node is a C32. + * @return FALSE - This node is not a C32. + * + */ +BOOLEAN +STATIC +MemRecNIsIdSupportedC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + if ((LogicalIdPtr->Revision & AMD_F10_C32_ALL) != 0) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.h b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.h new file mode 100755 index 0000000000..1866d60e2c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnc32.h @@ -0,0 +1,103 @@ +/** + * @file + * + * mnc32.h + * + * Northbridge C32 Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 13435 $ @e \$Date: 2009-05-12 02:26:55 +0800 (Tue, 12 May 2009) $ + * + **/ +/***************************************************************************** + * + * 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. + * + * *************************************************************************** + * + */ + +#ifndef _MRNC32_H_ +#define _MRNC32_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_NODE_C32 2 +#define MAX_CHANNELS_PER_DCT_C32 1 + +#define _4GB_RJ8 ((UINT32)4 << (30 - 8)) +#define MTRR_VALID 11 + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemRecConstructNBBlockC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +VOID +MemRecNSwitchDctC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ); + +VOID +MemRecNSwitchChannelC32 ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ); + +VOID +MemRecNFinalizeMctC32 ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MRNC32_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnmctc32.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnmctc32.c new file mode 100755 index 0000000000..b7b9f3c884 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnmctc32.c @@ -0,0 +1,126 @@ +/** + * @file + * + * mrnmctc32.c + * + * Northbridge C32 MCT supporting functions Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 13435 $ @e \$Date: 2009-05-12 02:26:55 +0800 (Tue, 12 May 2009) $ + * + **/ +/***************************************************************************** +* +* 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 "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrnc32.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNMCTC32_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets final values in BUCFG and BUCFG2 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNFinalizeMctC32 ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + S_UINT64 SMsr; + + MemPtr = NBPtr->MemPtr; + + // Recommended settings for F2x11C + MemRecNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x2CE00F60); + + LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (!NBPtr->ClToNbFlag) { + SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis + } + LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis + LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c new file mode 100755 index 0000000000..cf3dd17249 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/C32/mrnprotoc32.c @@ -0,0 +1,57 @@ +/** + * @file + * + * mrnprotoc32.c + * + * Northbridge support functions for Errata and early samples Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 10082 $ @e \$Date: 2008-12-17 20:21:26 +0800 (Wed, 17 Dec 2008) $ + * + **/ +/***************************************************************************** +* +* 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. +* +* *************************************************************************** +* +*/ + + + +#include "AGESA.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_C32_MRNPROTOC32_FILECODE +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.c new file mode 100755 index 0000000000..fa668dc5fa --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.c @@ -0,0 +1,640 @@ +/** + * @file + * + * mrnda.c + * + * Common Northbridge functions for Ridgeback Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrnda.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_DA_MRNDA_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemRecNInitNBRegTableDA ( + IN OUT TSEFO *NBRegTable + ); + +UINT32 +STATIC +MemRecNCmnGetSetFieldDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ); + +BOOLEAN +STATIC +MemRecNIsIdSupportedDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] NodeID - Node ID for this NB block + * + * @return TRUE - This node is a RB and this NB block has been initialized + * @return FALSE - This node is not a RB + */ + +BOOLEAN +MemRecConstructNBBlockDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemRecNIsIdSupportedDA (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + MCTPtr = &MemPtr->DiesPerSystem[NodeID]; + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_DA * ( + sizeof (CH_DEF_STRUCT) + ( + MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES + ) + ) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + } + } + + // + // Initialize NB block's variables + // + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->MCTPtr = MCTPtr; + NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + + NBPtr->DctCachePtr = NBPtr->DctCache; + + MemRecNInitNBRegTableDA (NBPtr->NBRegTable); + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); + + NBPtr->InitRecovery = MemRecNMemInitNb; + + NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; + NBPtr->SwitchDCT = MemRecNSwitchDctDA; + NBPtr->SwitchChannel = MemRecNSwitchChannelDA; + NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb; + NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; + NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; + NBPtr->sendZQCmd = MemRecNSendZQCmdNb; + NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb; + + NBPtr->GetBitField = MemRecNGetBitFieldNb; + NBPtr->SetBitField = MemRecNSetBitFieldNb; + NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; + NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; + NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldDA; + NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDA; + NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDA; + NBPtr->TrainingFlow = MemNRecTrainingFlowNb; + NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA; + NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE; + NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE; + MemRecNSwitchDctDA (NBPtr, 0); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemRecNSwitchDctDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + NBPtr->Dct = Dct & 1; + NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]); + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + + MemRecNSwitchChannelDA (NBPtr, NBPtr->Channel); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemRecNSwitchChannelDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = Channel & 1; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 Index; + UINT16 Offset; + UINT32 Value; + UINT32 Address; + UINT8 Dimm; + UINT8 Byte; + + Dimm = DRBN_DIMM (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + + ASSERT (Dimm < 4); + ASSERT (Byte < 8); + + switch (TrnDly) { + case AccessRcvEnDly: + Index = 0x10; + break; + case AccessWrDqsDly: + Index = 0x30; + break; + case AccessWrDatDly: + Index = 0x01; + break; + case AccessRdDqsDly: + Index = 0x05; + break; + case AccessPhRecDly: + Index = 0x50; + break; + default: + Index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + Index += (Dimm * 3); + if (Byte & 0x04) { + // if byte 4,5,6,7 + Index += 0x10; + } + if (Byte & 0x02) { + // if byte 2,3,6,7 + Index++; + } + Offset = 16 * (Byte % 2); + break; + + case AccessRdDqsDly: + Field &= ~ 0x0001; + case AccessWrDatDly: + Index += (Dimm * 0x100); + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + Index += (Byte / 4); + Offset = 8 * (Byte % 4); + break; + default: + Offset = 0; + IDS_ERROR_TRAP; + } + + Address = Index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + + if (IsSet) { + if (TrnDly == AccessPhRecDly) { + Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; + } + + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; + } + } else { + Value = (Value >> Offset) & 0xFF; + } + + return Value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] IsSet - Indicates if the function will set or get + * @param[in] FieldName - Name of field to be set + * @param[in] Field - Value to be programmed + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNCmnGetSetFieldDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + SBDFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + + Value = 0; + if (FieldName < BFEndOfList) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = TSEFO_TYPE (Address); + + // If Fn2 and DCT1 selected, set Address to be 1xx + if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) { + Address |= 0x0100; + } + if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) { + // Special DCT Phy access + Address &= 0x0FFFFFFF; + Lowbit = 0; + Highbit = 16; + } else { + // Normal DCT Phy access + Address = TSEFO_OFFSET (Address); + } + + + if (Type == NB_ACCESS) { + Address |= (((UINT32) (24 + 0)) << 15); + PciAddr.AddressValue = Address; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + } else { + IDS_ERROR_TRAP; + } + + if (IsSet) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + } else { + IDS_ERROR_TRAP; + } + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + } + } + } else { + IDS_ERROR_TRAP; // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes bit field translation table + * + * @param[in,out] *NBRegTable - Pointer to the NB Table * + */ + +VOID +STATIC +MemRecNInitNBRegTableDA ( + IN OUT TSEFO *NBRegTable + ) +{ + UINT16 i; + for (i = 0; i <= BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp); + +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemRecNIsIdSupportedDA + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + */ +BOOLEAN +STATIC +MemRecNIsIdSupportedDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + + if ((LogicalIdPtr->Revision & (AMD_F10_BL_ALL | AMD_F10_DA_ALL)) != 0) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.h b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.h new file mode 100755 index 0000000000..bb91de879d --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnda.h @@ -0,0 +1,104 @@ +/** + * @file + * + * mnda.h + * + * Northbridge Ridgeback Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** + * + * 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. + * + * *************************************************************************** + * + */ + +#ifndef _MRNDA_H_ +#define _MRNDA_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_NODE_DA 2 +#define MAX_CHANNELS_PER_DCT_DA 1 + +#define _4GB_RJ8 ((UINT32)4 << (30 - 8)) +#define MTRR_VALID 11 + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemRecConstructNBBlockDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +VOID +MemRecNSwitchDctDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ); + +VOID +MemRecNSwitchChannelDA ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ); + +VOID +MemRecNFinalizeMctDA ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + + +#endif /* _MRNDA_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnmctda.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnmctda.c new file mode 100755 index 0000000000..fef338d71f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DA/mrnmctda.c @@ -0,0 +1,129 @@ +/** + * @file + * + * mrnmctda.c + * + * Northbridge DA MCT supporting functions Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrnda.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_DA_MRNMCTDA_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets final values in BUCFG and BUCFG2 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNFinalizeMctDA ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + S_UINT64 SMsr; + + MemPtr = NBPtr->MemPtr; + + + // Recommended settings for F2x11C + MemRecNSetBitFieldNb (NBPtr, BFMctWrLimit, 16); + MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); + MemRecNSetBitFieldNb (NBPtr, BFPrefIoDis, 0); + MemRecNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1); + + LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (!NBPtr->ClToNbFlag) { + SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis + } + LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis + LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.c new file mode 100755 index 0000000000..e21d498b71 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.c @@ -0,0 +1,644 @@ +/** + * @file + * + * mrndr.c + * + * Common Northbridge functions for Ridgeback Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrndr.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_DR_MRNDR_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemRecNInitNBRegTableDR ( + IN OUT TSEFO *NBRegTable + ); + +UINT32 +STATIC +MemRecNCmnGetSetFieldDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ); + +BOOLEAN +STATIC +MemRecNIsIdSupportedDr ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] NodeID - Node ID for this NB block + * + * @return TRUE - This node is a RB and this NB block has been initialized + * @return FALSE - This node is not a RB + */ + +BOOLEAN +MemRecConstructNBBlockDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemRecNIsIdSupportedDr (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + MCTPtr = &MemPtr->DiesPerSystem[NodeID]; + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DR * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_DR * ( + sizeof (CH_DEF_STRUCT) + ( + MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES + ) + ) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_DR; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DR * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DR; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DR; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DR * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DR; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + } + } + + // + // Initialize NB block's variables + // + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->MCTPtr = MCTPtr; + NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + + NBPtr->DctCachePtr = NBPtr->DctCache; + + MemRecNInitNBRegTableDR (NBPtr->NBRegTable); + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); + + NBPtr->InitRecovery = MemRecNMemInitNb; + + NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; + NBPtr->SwitchDCT = MemRecNSwitchDctDR; + NBPtr->SwitchChannel = MemRecNSwitchChannelDR; + NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb; + NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; + NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; + NBPtr->sendZQCmd = MemRecNSendZQCmdNb; + NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb; + + NBPtr->GetBitField = MemRecNGetBitFieldNb; + NBPtr->SetBitField = MemRecNSetBitFieldNb; + NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; + NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; + NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldDR; + NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyDR; + NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctDR; + NBPtr->TrainingFlow = MemNRecTrainingFlowNb; + NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDR; + NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE; + NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE; + MemRecNSwitchDctDR (NBPtr, 0); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemRecNSwitchDctDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + NBPtr->Dct = Dct & 1; + NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]); + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + + MemRecNSwitchChannelDR (NBPtr, NBPtr->Channel); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemRecNSwitchChannelDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = Channel & 1; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 Index; + UINT16 Offset; + UINT32 Value; + UINT32 Address; + UINT8 Dimm; + UINT8 Byte; + + Dimm = DRBN_DIMM (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + + ASSERT (Dimm < 4); + ASSERT (Byte < 8); + + switch (TrnDly) { + case AccessRcvEnDly: + Index = 0x10; + break; + case AccessWrDqsDly: + Index = 0x30; + break; + case AccessWrDatDly: + Index = 0x01; + break; + case AccessRdDqsDly: + Index = 0x05; + break; + case AccessPhRecDly: + Index = 0x50; + break; + default: + Index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + Index += (Dimm * 3); + if (Byte & 0x04) { + // if byte 4,5,6,7 + Index += 0x10; + } + if (Byte & 0x02) { + // if byte 2,3,6,7 + Index++; + } + Offset = 16 * (Byte % 2); + break; + + case AccessRdDqsDly: + Field &= ~ 0x0001; + case AccessWrDatDly: + Index += (Dimm * 0x100); + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + Index += (Byte / 4); + Offset = 8 * (Byte % 4); + break; + default: + Offset = 0; + IDS_ERROR_TRAP; + } + + Address = Index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + + if (IsSet) { + if (TrnDly == AccessPhRecDly) { + Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; + } + + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; + } + } else { + Value = (Value >> Offset) & 0xFF; + } + + return Value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] IsSet - Indicates if the function will set or get + * @param[in] FieldName - Name of field to be set + * @param[in] Field - Value to be programmed + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNCmnGetSetFieldDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + SBDFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + + Value = 0; + if (FieldName < BFEndOfList) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = TSEFO_TYPE (Address); + + // If Fn2 and DCT1 selected, set Address to be 1xx + if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) { + Address |= 0x0100; + } + if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) { + // Special DCT Phy access + Address &= 0x0FFFFFFF; + Lowbit = 0; + Highbit = 16; + } else { + // Normal DCT Phy access + Address = TSEFO_OFFSET (Address); + } + + + if (Type == NB_ACCESS) { + Address |= (((UINT32) (24 + 0)) << 15); + PciAddr.AddressValue = Address; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + } else { + IDS_ERROR_TRAP; + } + + if (IsSet) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + } else { + IDS_ERROR_TRAP; + } + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + } + } + } else { + IDS_ERROR_TRAP; // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes bit field translation table + * + * @param[in,out] *NBRegTable - Pointer to the NB Table * + */ + +VOID +STATIC +MemRecNInitNBRegTableDR ( + IN OUT TSEFO *NBRegTable + ) +{ + UINT16 i; + for (i = 0; i <= BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp); + +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemRecNIsIdSupportedDr + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + */ +BOOLEAN +STATIC +MemRecNIsIdSupportedDr ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + + if ((LogicalIdPtr->Revision & (AMD_F10_RB_ALL + | AMD_F10_BL_ALL + | AMD_F10_DA_ALL )) != 0) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.h b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.h new file mode 100755 index 0000000000..ecc0ac4884 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrndr.h @@ -0,0 +1,103 @@ +/** + * @file + * + * mndr.h + * + * Northbridge Ridgeback Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** + * + * 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. + * + * *************************************************************************** + * + */ + +#ifndef _MRNDR_H_ +#define _MRNDR_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_NODE_DR 2 +#define MAX_CHANNELS_PER_DCT_DR 1 + +#define _4GB_RJ8 ((UINT32)4 << (30 - 8)) +#define MTRR_VALID 11 + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemRecConstructNBBlockDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +VOID +MemRecNSwitchDctDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ); + +VOID +MemRecNSwitchChannelDR ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ); + +VOID +MemRecNFinalizeMctDR ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MRNDR_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrnmctdr.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrnmctdr.c new file mode 100755 index 0000000000..a6243fd2f5 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/DR/mrnmctdr.c @@ -0,0 +1,130 @@ +/** + * @file + * + * mrnmctdr.c + * + * Northbridge DR MCT supporting functions Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mrndr.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_DR_MRNMCTDR_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets final values in BUCFG and BUCFG2 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNFinalizeMctDR ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + S_UINT64 SMsr; + + MemPtr = NBPtr->MemPtr; + + + // Recommended settings for F2x11C + MemRecNSetBitFieldNb (NBPtr, BFMctWrLimit, 16); + MemRecNSetBitFieldNb (NBPtr, BFPrefCpuDis, 0); + MemRecNSetBitFieldNb (NBPtr, BFPrefIoDis, 0); + MemRecNSetBitFieldNb (NBPtr, BFFlushWrOnStpGnt, 1); + + LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (!NBPtr->ClToNbFlag) { + SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis + } + LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis + LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrndcthy.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrndcthy.c new file mode 100755 index 0000000000..97ad7b37c8 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrndcthy.c @@ -0,0 +1,152 @@ +/** + * @file + * + * mrndctHy.c + * + * Northbridge DCT support for Hydra 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 "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Ids.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mru.h" +#include "mrnhy.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNDCTHY_FILECODE + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * Set Dram ODT for mission mode and write leveling mode. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] OdtMode - Mission mode or write leveling mode + * @param[in] ChipSelect - Chip select number + * @param[in] TargetCS - Chip select number that is being trained + * + */ + +VOID +MemRecNSetDramOdtHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN ODT_MODE OdtMode, + IN UINT8 ChipSelect, + IN UINT8 TargetCS + ) +{ + UINT8 Dimms; + UINT8 *DimmsPerChPtr; + UINT8 MaxDimmsPerChannel; + UINT8 DramTerm; + UINT8 DramTermDyn; + UINT8 WrLvOdt; + BOOLEAN IsDualRank; + + Dimms = NBPtr->ChannelPtr->Dimms; + IsDualRank = ((NBPtr->ChannelPtr->DimmDrPresent & (UINT8) 1 << (ChipSelect >> 1)) != 0) ? TRUE : FALSE; + + // Dram nominal termination + if (Dimms == 1) { + DramTerm = 1; // 60 Ohms + } else { + DramTerm = 3; // 40 Ohms + } + + // Dram dynamic termination + if (Dimms < 2) { + DramTermDyn = 0; // Disabled + } else { + DramTermDyn = 2; // 120 Ohms + } + + if (OdtMode == WRITE_LEVELING_MODE) { + if (ChipSelect == TargetCS) { + DramTerm = DramTermDyn; + + // Program WrLvOdt, the target DIMM should be the closest DIMM. + DimmsPerChPtr = MemRecFindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, 0, NBPtr->ChannelPtr->ChannelID); + if (DimmsPerChPtr != NULL) { + MaxDimmsPerChannel = *DimmsPerChPtr; + } else { + MaxDimmsPerChannel = 2; + } + + if (MaxDimmsPerChannel == 3) { + if (NBPtr->ChannelPtr->DimmQrPresent != 0) { + WrLvOdt = 0xF; + } else { + WrLvOdt = 7; + } + } else { + if (NBPtr->ChannelPtr->DimmQrPresent != 0) { + WrLvOdt = 0xB; + } else if (Dimms == 2) { + WrLvOdt = 3; + } else if (IsDualRank) { + WrLvOdt = 8; + } else { + WrLvOdt = 2; + } + } + MemRecNSetBitFieldNb (NBPtr, BFWrLvOdt, WrLvOdt); + } + } + MemRecNSetBitFieldNb (NBPtr, BFDramTerm, DramTerm); + MemRecNSetBitFieldNb (NBPtr, BFDramTermDyn, DramTermDyn); +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.c new file mode 100755 index 0000000000..0541703719 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.c @@ -0,0 +1,700 @@ +/** + * @file + * + * mrnhy.c + * + * Common Northbridge functions for Hydra 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 "mrport.h" +#include "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mm.h" +#include "mn.h" +#include "mrnhy.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNHY_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define MAX_DCTS_PER_DIE 2 +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemRecNInitNBRegTableHy ( + IN OUT TSEFO *NBRegTable + ); + +UINT32 +STATIC +MemRecNCmnGetSetFieldHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ); + +BOOLEAN +STATIC +MemRecNIsIdSupportedHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +VOID +STATIC +MemRecNSwitchNodeHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID + ); + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] NodeID - Node ID for this NB block + * + * @return TRUE - This node is a Hydra and this NB block has been initialized + * @return FALSE - This node is not a Hydra + */ + +BOOLEAN +MemRecConstructNBBlockHY ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemRecNIsIdSupportedHy (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + MCTPtr = &MemPtr->DiesPerSystem[NodeID]; + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_HY * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_HY * ( + sizeof (CH_DEF_STRUCT) + ( + MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES + ) + ) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_HY; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + MemPtr->DiesPerSystem[NodeID + 1].DctCount = MAX_DCTS_PER_NODE_HY; + MemPtr->DiesPerSystem[NodeID + 1].DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_HY * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_HY; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_HY; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].ChannelID = (MCTPtr->DieId * 2) + Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_HY * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_HY; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + } + } + + // + // Initialize NB block's variables + // + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->MCTPtr = MCTPtr; + NBPtr->AllNodeMCTPtr = &MemPtr->DiesPerSystem[NodeID]; + NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + + NBPtr->DctCachePtr = NBPtr->DctCache; + + MemRecNInitNBRegTableHy (NBPtr->NBRegTable); + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); + + NBPtr->InitRecovery = MemRecNMemInitNb; + + NBPtr->SwitchNodeRec = MemRecNSwitchNodeHy; + NBPtr->SwitchDCT = MemRecNSwitchDctHy; + NBPtr->SwitchChannel = MemRecNSwitchChannelHy; + NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb; + NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; + NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; + NBPtr->sendZQCmd = MemRecNSendZQCmdNb; + NBPtr->SetDramOdtRec = MemRecNSetDramOdtHy; + + NBPtr->GetBitField = MemRecNGetBitFieldNb; + NBPtr->SetBitField = MemRecNSetBitFieldNb; + NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; + NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; + + NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldHy; + NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyHy; + NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctHy; + NBPtr->TrainingFlow = MemNRecTrainingFlowNb; + NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctHy; + NBPtr->IsSupported[DramModeAfterDimmPres] = TRUE; + MemRecNSwitchDctHy (NBPtr, 0); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function sets the current die to work on. + * Should be called before accessing a certain die + * All data structures will be updated to point to the current node + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] NodeID - ID of the target die + * + */ + +VOID +STATIC +MemRecNSwitchNodeHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 NodeID + ) +{ + NBPtr->MCTPtr = &(NBPtr->AllNodeMCTPtr[NodeID]); + NBPtr->Node = NodeID; + NBPtr->MCTPtr->NodeId = NodeID; + MemRecNSwitchDctHy (NBPtr, NBPtr->Dct); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemRecNSwitchDctHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + NBPtr->Dct = Dct & 1; + NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[(NBPtr->MCTPtr->NodeId * MAX_DCTS_PER_DIE + Dct) * MAX_DIMMS_PER_CHANNEL]); + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + + MemRecNSwitchChannelHy (NBPtr, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemRecNSwitchChannelHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = 0; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[0]); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 index; + UINT16 offset; + UINT32 value; + UINT32 address; + UINT8 DIMM; + UINT8 Rank; + UINT8 Byte; + UINT8 Nibble; + + DIMM = DRBN_DIMM (DrbnVar); + Rank = DRBN_RANK (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + Nibble = DRBN_NBBL (DrbnVar); + + switch (TrnDly) { + case AccessRcvEnDly: + index = 0x10; + break; + case AccessWrDqsDly: + index = 0x30; + break; + case AccessWrDatDly: + index = 0x01; + break; + case AccessRdDqsDly: + index = 0x05; + break; + case AccessPhRecDly: + index = 0x50; + break; + default: + index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + index += (DIMM * 3); + if ((Byte & 0x04) != 0) { + // if byte 4,5,6,7 + index += 0x10; + } + if ((Byte & 0x02) != 0) { + // if byte 2,3,6,7 + index++; + } + if (Byte > 7) { + index += 2; + } + offset = 16 * (Byte % 2); + index |= (Rank << 8); + index |= (Nibble << 9); + break; + + case AccessRdDqsDly: + Field &= ~ 0x0001; + case AccessWrDatDly: + index += (DIMM * 0x100); + if (Nibble != 0) { + if (Rank != 0) { + index += 0xA0; + } else { + index += 0x70; + } + } else if (Rank != 0) { + index += 0x60; + } + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + index += (Byte / 4); + offset = 8 * (Byte % 4); + break; + default: + offset = 0; + IDS_ERROR_TRAP; + } + + address = index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + + if (IsSet != 0) { + if (TrnDly == AccessPhRecDly) { + value = NBPtr->DctCachePtr->PhRecReg[index & 0x03]; + } + + value = ((UINT32)Field << offset) | (value & (~((UINT32)0xFF << offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, value); + address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[index & 0x03] = value; + } + } else { + value = (value >> offset) & 0xFF; + } + + return value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Name of Field to be set + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNCmnGetSetFieldHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + SBDFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + + Value = 0; + if (FieldName < BFEndOfList) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address != 0) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = TSEFO_TYPE (Address); + + // If Fn2 and DCT1 selected, set Address to be 1xx + if (((Address & 0xF000) == 0x2000) && (NBPtr->Dct != 0)) { + Address |= 0x0100; + } + if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) { + // Special DCT Phy access + Address &= 0x0FFFFFFF; + Lowbit = 0; + Highbit = 16; + } else { + // Normal DCT Phy access + Address = TSEFO_OFFSET (Address); + } + + + if (Type == NB_ACCESS) { + // Address |= (((UINT32) (24 + 0)) << 15); + PciAddr.AddressValue = Address; + // Fix for MCM + PciAddr.Address.Device = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Device; + PciAddr.Address.Bus = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Bus; + PciAddr.Address.Segment = NBPtr->MemPtr->DiesPerSystem[NBPtr->Node].PciAddr.Address.Segment; + Address = PciAddr.AddressValue; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + } else { + IDS_ERROR_TRAP; + } + + if (IsSet != 0) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + } else { + IDS_ERROR_TRAP; + } + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + } + } + } else { + IDS_ERROR_TRAP; // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes bit field translation table + * +* @param[in,out] *NBRegTable - Pointer to the NB Table * + */ + +VOID +STATIC +MemRecNInitNBRegTableHy ( + IN OUT TSEFO *NBRegTable + ) +{ + UINT16 i; + for (i = 0; i <= BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 5, 5, BFSubMemclkRegDly); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 31, 0, BFMctCfgHiReg); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp); + +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemRecNIsIdSupportedHy + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + * @return TRUE - This node is a Hydra. + * @return FALSE - This node is not a Hydra. + * + */ +BOOLEAN +STATIC +MemRecNIsIdSupportedHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + if ((LogicalIdPtr->Revision & AMD_F10_HY_ALL) != 0) { + return TRUE; + } else { + return FALSE; + } +}
\ No newline at end of file diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.h b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.h new file mode 100755 index 0000000000..ff36edd7bf --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnhy.h @@ -0,0 +1,111 @@ +/** + * @file + * + * mnhy.h + * + * Northbridge Hydra 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. + * + * *************************************************************************** + * + */ + +#ifndef _MRNHY_H_ +#define _MRNHY_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define MAX_DCTS_PER_NODE_HY 2 +#define MAX_CHANNELS_PER_DCT_HY 1 + +#define _4GB_RJ8 ((UINT32)4 << (30 - 8)) +#define MTRR_VALID 11 + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemRecConstructNBBlockHY ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +VOID +MemRecNSwitchDctHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ); + +VOID +MemRecNSwitchChannelHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ); + +VOID +MemRecNSetDramOdtHy ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN ODT_MODE OdtMode, + IN UINT8 ChipSelect, + IN UINT8 TargetCS + ); + +VOID +MemRecNFinalizeMctHy ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +#endif /* _MRNHY_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnmcthy.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnmcthy.c new file mode 100755 index 0000000000..5c65d5f96c --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnmcthy.c @@ -0,0 +1,126 @@ +/** + * @file + * + * mrnmctdr.c + * + * Northbridge DR MCT supporting functions 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 "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrnhy.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNMCTHY_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets final values in BUCFG and BUCFG2 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNFinalizeMctHy ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + S_UINT64 SMsr; + + MemPtr = NBPtr->MemPtr; + + // Recommended settings for F2x11C + MemRecNSetBitFieldNb (NBPtr, BFMctCfgHiReg, 0x2CE00F60); + + LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (!NBPtr->ClToNbFlag) { + SMsr.lo &= ~((UINT32) 1 << 15); // ClLinesToNbDis + } + LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.hi &= ~((UINT32) 1 << (48 - 32)); // WbEnhWsbDis + LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnprotohy.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnprotohy.c new file mode 100755 index 0000000000..8dc35f5510 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/HY/mrnprotohy.c @@ -0,0 +1,57 @@ +/** + * @file + * + * mrnproto.c + * + * Northbridge support functions for Errata and early samples 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. +* +* *************************************************************************** +* +*/ + + + +#include "AGESA.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_HY_MRNPROTOHY_FILECODE +/* + *----------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *----------------------------------------------------------------------------- + */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.c new file mode 100755 index 0000000000..beaf1c6ebc --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.c @@ -0,0 +1,641 @@ +/** + * @file + * + * mrnNi.c + * + * Common Northbridge functions for Nile Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mrnda.h" +#include "mrnNi.h" +#include "heapManager.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_NI_MRNNI_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +VOID +STATIC +MemRecNInitNBRegTableNi ( + IN OUT TSEFO *NBRegTable + ); + +UINT32 +STATIC +MemRecNCmnGetSetFieldNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ); + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ); + +BOOLEAN +STATIC +MemRecNIsIdSupportedNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes the northbridge block + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT + * @param[in] NodeID - Node ID for this NB block + * + * @return TRUE - This node is a RB and this NB block has been initialized + * @return FALSE - This node is not a RB + */ + +BOOLEAN +MemRecConstructNBBlockNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ) +{ + UINT8 Dct; + UINT8 Channel; + DIE_STRUCT *MCTPtr; + ALLOCATE_HEAP_PARAMS AllocHeapParams; + + // + // Determine if this is the expected NB Type + // + GetLogicalIdOfSocket (MemPtr->DiesPerSystem[NodeID].SocketId, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + if (!MemRecNIsIdSupportedNi (NBPtr, &(MemPtr->DiesPerSystem[NodeID].LogicalCpuid))) { + return FALSE; + } + + // + // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs + // + MCTPtr = &MemPtr->DiesPerSystem[NodeID]; + AllocHeapParams.RequestedBufferSize = MAX_DCTS_PER_NODE_DA * ( + sizeof (DCT_STRUCT) + ( + MAX_CHANNELS_PER_DCT_DA * ( + sizeof (CH_DEF_STRUCT) + ( + MAX_DIMMS * MAX_DELAYS * NUMBER_OF_DELAY_TABLES + ) + ) + ) + ); + AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0); + AllocHeapParams.Persist = HEAP_LOCAL_CACHE; + if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) { + return FALSE; + } + + MCTPtr->DctCount = MAX_DCTS_PER_NODE_DA; + MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += MAX_DCTS_PER_NODE_DA * sizeof (DCT_STRUCT); + for (Dct = 0; Dct < MAX_DCTS_PER_NODE_DA; Dct++) { + MCTPtr->DctData[Dct].Dct = Dct; + MCTPtr->DctData[Dct].ChannelCount = MAX_CHANNELS_PER_DCT_DA; + MCTPtr->DctData[Dct].ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[0].ChannelID = Dct; + AllocHeapParams.BufferPtr += MAX_CHANNELS_PER_DCT_DA * sizeof (CH_DEF_STRUCT); + for (Channel = 0; Channel < MAX_CHANNELS_PER_DCT_DA; Channel++) { + MCTPtr->DctData[Dct].ChData[Channel].RcvEnDlys = (UINT16 *) AllocHeapParams.BufferPtr; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS) * 2; + MCTPtr->DctData[Dct].ChData[Channel].WrDqsDlys = AllocHeapParams.BufferPtr; + MCTPtr->DctData[Dct].ChData[Channel].Dct = Dct; + AllocHeapParams.BufferPtr += (MAX_DIMMS * MAX_DELAYS); + } + } + + // + // Initialize NB block's variables + // + NBPtr->MemPtr = MemPtr; + NBPtr->RefPtr = MemPtr->ParameterListPtr; + NBPtr->MCTPtr = MCTPtr; + NBPtr->SPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + NBPtr->AllNodeSPDPtr = &MemPtr->SpdDataStructure[MemPtr->DiesPerSystem[NodeID].SocketId * MAX_CHANNELS_PER_SOCKET * MAX_DIMMS_PER_CHANNEL]; + + NBPtr->DctCachePtr = NBPtr->DctCache; + + MemRecNInitNBRegTableNi (NBPtr->NBRegTable); + NBPtr->Dct = 0; + NBPtr->Channel = 0; + NBPtr->VarMtrrHiMsk = MemRecGetVarMtrrHiMsk (&(MemPtr->DiesPerSystem[NodeID].LogicalCpuid), &(MemPtr->StdHeader)); + + LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader); + LibAmdMemFill (NBPtr->IsSupported, FALSE, sizeof (NBPtr->IsSupported), &NBPtr->MemPtr->StdHeader); + + NBPtr->InitRecovery = MemRecNMemInitNb; + + NBPtr->SwitchNodeRec = (VOID (*) (MEM_NB_BLOCK *, UINT8)) MemRecDefRet; + NBPtr->SwitchDCT = MemRecNSwitchDctNi; + NBPtr->SwitchChannel = MemRecNSwitchChannelNi; + NBPtr->SetMaxLatency = MemRecNSetMaxLatencyNb; + NBPtr->GetSysAddrRec = MemRecNGetMCTSysAddrNb; + NBPtr->SendMrsCmd = MemRecNSendMrsCmdNb; + NBPtr->sendZQCmd = MemRecNSendZQCmdNb; + NBPtr->SetDramOdtRec = MemRecNSetDramOdtNb; + + NBPtr->GetBitField = MemRecNGetBitFieldNb; + NBPtr->SetBitField = MemRecNSetBitFieldNb; + NBPtr->GetTrainDly = MemRecNGetTrainDlyNb; + NBPtr->SetTrainDly = MemRecNSetTrainDlyNb; + NBPtr->MemRecNCmnGetSetFieldNb = MemRecNCmnGetSetFieldNi; + NBPtr->MemRecNcmnGetSetTrainDlyNb = MemRecNcmnGetSetTrainDlyNi; + NBPtr->MemRecNSwitchDctNb = MemRecNSwitchDctNi; + NBPtr->TrainingFlow = MemNRecTrainingFlowNb; + NBPtr->MemRecNFinalizeMctNb = MemRecNFinalizeMctDA; + NBPtr->IsSupported[DramModeBeforeDimmPres] = TRUE; + NBPtr->IsSupported[CheckClearOnDimmMirror] = TRUE; + MemRecNSwitchDctNi (NBPtr, 0); + + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current DCT to work on. + * Should be called before accessing a certain DCT + * All data structures will be updated to point to the current DCT + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Dct - ID of the target DCT + * + */ + +VOID +MemRecNSwitchDctNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ) +{ + NBPtr->Dct = Dct & 1; + NBPtr->SPDPtr = &(NBPtr->AllNodeSPDPtr[Dct * MAX_DIMMS_PER_CHANNEL]); + NBPtr->DCTPtr = &(NBPtr->MCTPtr->DctData[NBPtr->Dct]); + + MemRecNSwitchChannelNi (NBPtr, NBPtr->Channel); +} +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the current channel to work on. + * Should be called before accessing a certain channel + * All data structures will be updated to point to the current channel + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] Channel - ID of the target channel + * + */ + +VOID +MemRecNSwitchChannelNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ) +{ + NBPtr->Channel = Channel & 1; + NBPtr->ChannelPtr = &(NBPtr->DCTPtr->ChData[NBPtr->Channel]); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or set DQS timing during training. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * @param[in] IsSet - Indicates if the function will set or get + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNcmnGetSetTrainDlyNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + UINT16 Index; + UINT16 Offset; + UINT32 Value; + UINT32 Address; + UINT8 Dimm; + UINT8 Byte; + + Dimm = DRBN_DIMM (DrbnVar); + Byte = DRBN_BYTE (DrbnVar); + + ASSERT (Dimm < 4); + ASSERT (Byte < 8); + + switch (TrnDly) { + case AccessRcvEnDly: + Index = 0x10; + break; + case AccessWrDqsDly: + Index = 0x30; + break; + case AccessWrDatDly: + Index = 0x01; + break; + case AccessRdDqsDly: + Index = 0x05; + break; + case AccessPhRecDly: + Index = 0x50; + break; + default: + Index = 0; + IDS_ERROR_TRAP; + } + + switch (TrnDly) { + case AccessRcvEnDly: + case AccessWrDqsDly: + Index += (Dimm * 3); + if (Byte & 0x04) { + // if byte 4,5,6,7 + Index += 0x10; + } + if (Byte & 0x02) { + // if byte 2,3,6,7 + Index++; + } + Offset = 16 * (Byte % 2); + break; + + case AccessRdDqsDly: + Field &= ~ 0x0001; + case AccessWrDatDly: + Index += (Dimm * 0x100); + // break is not being used here because AccessRdDqsDly and AccessWrDatDly also need + // to run AccessPhRecDly sequence. + case AccessPhRecDly: + Index += (Byte / 4); + Offset = 8 * (Byte % 4); + break; + default: + Offset = 0; + IDS_ERROR_TRAP; + } + + Address = Index; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + + if (IsSet) { + if (TrnDly == AccessPhRecDly) { + Value = NBPtr->DctCachePtr->PhRecReg[Index & 0x03]; + } + + Value = ((UINT32)Field << Offset) | (Value & (~((UINT32)0xFF << Offset))); + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + if (TrnDly == AccessPhRecDly) { + NBPtr->DctCachePtr->PhRecReg[Index & 0x03] = Value; + } + } else { + Value = (Value >> Offset) & 0xFF; + } + + return Value; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets or sets a value to a bit field in a PCI register. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] IsSet - Indicates if the function will set or get + * @param[in] FieldName - Name of field to be set + * @param[in] Field - Value to be programmed + * + * @return value read, if the function is used as a "get" + */ + +UINT32 +STATIC +MemRecNCmnGetSetFieldNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 IsSet, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + SBDFO Address; + PCI_ADDR PciAddr; + UINT8 Type; + UINT32 Value; + UINT32 Highbit; + UINT32 Lowbit; + UINT32 Mask; + + Value = 0; + if (FieldName < BFEndOfList) { + Address = NBPtr->NBRegTable[FieldName]; + if (Address) { + Lowbit = TSEFO_END (Address); + Highbit = TSEFO_START (Address); + Type = TSEFO_TYPE (Address); + + // If Fn2 and DCT1 selected, set Address to be 1xx + if (((Address & 0xF000) == 0x2000) && NBPtr->Dct) { + Address |= 0x0100; + } + if ((Address >> 29) == ((DCT_PHY_ACCESS << 1) | 1)) { + // Special DCT Phy access + Address &= 0x0FFFFFFF; + Lowbit = 0; + Highbit = 16; + } else { + // Normal DCT Phy access + Address = TSEFO_OFFSET (Address); + } + + + if (Type == NB_ACCESS) { + Address |= (((UINT32) (24 + 0)) << 15); + PciAddr.AddressValue = Address; + LibAmdPciRead (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + + Value = MemRecNGetBitFieldNb (NBPtr, BFDctAddlDataReg); + } else { + IDS_ERROR_TRAP; + } + + if (IsSet) { + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Mask = (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } else { + Mask = (UINT32)0xFFFFFFFF; + } + Value &= ~(Mask << Lowbit); + Value |= (Field & Mask) << Lowbit; + + if (Type == NB_ACCESS) { + PciAddr.AddressValue = Address; + LibAmdPciWrite (AccessWidth32, PciAddr , &Value, &NBPtr->MemPtr->StdHeader); + } else if (Type == DCT_PHY_ACCESS) { + MemRecNSetBitFieldNb (NBPtr, BFDctAddlDataReg, Value); + Address |= DCT_ACCESS_WRITE; + + MemRecNSetBitFieldNb (NBPtr, BFDctAddlOffsetReg, Address); + while (MemRecNGetBitFieldNb (NBPtr, BFDctAccessDone) == 0) {} + } else { + IDS_ERROR_TRAP; + } + } else { + Value = Value >> Lowbit; // Shift + // A 1<<32 == 1<<0 due to x86 SHL instruction, so skip if that is the case + if ((Highbit - Lowbit) != 31) { + Value &= (((UINT32)1 << (Highbit - Lowbit + 1)) - 1); + } + } + } + } else { + IDS_ERROR_TRAP; // Invalid bit field index + } + return Value; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function initializes bit field translation table + * + * @param[in,out] *NBRegTable - Pointer to the NB Table * + */ + +VOID +STATIC +MemRecNInitNBRegTableNi ( + IN OUT TSEFO *NBRegTable + ) +{ + UINT16 i; + for (i = 0; i <= BFEndOfList; i++) { + NBRegTable[i] = 0; + } + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x00), 31, 0, BFDevVendorIDReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (0, 0x60), 2, 0, BFNodeID); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x40), 31, 0, BFDramBaseReg0); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (1, 0x44), 31, 0, BFDramLimitReg0); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x40), 31, 0, BFCSBaseAddr0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x44), 31, 0, BFCSBaseAddr1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x48), 31, 0, BFCSBaseAddr2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x4C), 31, 0, BFCSBaseAddr3Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x50), 31, 0, BFCSBaseAddr4Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x54), 31, 0, BFCSBaseAddr5Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x58), 31, 0, BFCSBaseAddr6Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x5C), 31, 0, BFCSBaseAddr7Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x60), 31, 0, BFCSMask0Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x64), 31, 0, BFCSMask1Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x68), 31, 0, BFCSMask2Reg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x6C), 31, 0, BFCSMask3Reg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 0, BFDramControlReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 0, BFDramInitRegReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x80), 31, 0, BFDramBankAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 31, 0, BFDramMRSReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 9, 7, BFDramTerm); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x84), 11, 10, BFDramTermDyn); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x88), 31, 0, BFDramTimingLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 31, 0, BFDramTimingHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 31, 0, BFDramConfigLoReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 31, 0, BFDramConfigHiReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 0, BFDctAddlOffsetReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x9C), 31, 0, BFDctAddlDataReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x98), 31, 31, BFDctAccessDone); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (3, 0xD4), 4, 0, BFNbFid); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 18, 18, BFDqsRcvEnTrain); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x78), 31, 22, BFMaxLatency); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 15, 0, BFMrsAddress); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 18, 16, BFMrsBank); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 22, 20, BFMrsChipSel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 26, 26, BFSendMrsCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 27, 27, BFDeassertMemRstX); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 28, 28, BFAssertCke); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 29, 29, BFSendZQCmd); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 30, 30, BFSendCtrlWord); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 31, 31, BFEnDramInit); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 7, 7, BFLevel); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x7C), 12, 12, BFMrsQoff); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x8C), 18, 18, BFDisAutoRefresh); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 0, 0, BFInitDram); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x90), 16, 16, BFUnBuffDimm); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 8, 8, BFDdr3Mode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 9, 9, BFLegacyBiosMode); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 11, 10, BFZqcsInterval); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x94), 14, 14, BFDisDramInterface); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 6, 6, BFOdtSwizzle); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0xA8), 15, 8, BFCtrlWordCS); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 8, 8, BFDramEnabled); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x110), 31, 0, BFDctSelBaseAddrReg); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x114), 31, 0, BFDctSelBaseOffsetReg); + + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 6, 2, BFMctWrLimit); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 12, 12, BFPrefCpuDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 13, 13, BFPrefIoDis); + MAKE_TSEFO (NBRegTable, NB_ACCESS, _FN (2, 0x11C), 29, 29, BFFlushWrOnStpGnt); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x00, 31, 0, BFODCControl); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x04, 31, 0, BFAddrTmgControl); + + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 0, 0, BFWrtLvTrEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 1, 1, BFWrtLvTrMode); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 5, 4, BFTrDimmSel); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 11, 8, BFWrLvOdt); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 12, 12, BFWrLvOdtEn); + MAKE_TSEFO (NBRegTable, DCT_PHY_ACCESS, 0x08, 30, 30, BFDisAutoComp); + +} + +/*-----------------------------------------------------------------------------*/ +/** + * MemRecNIsIdSupportedNi + * This function matches the CPU_LOGICAL_ID with certain criteria to + * determine if it is supported by this NBBlock. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * + */ +BOOLEAN +STATIC +MemRecNIsIdSupportedNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN CPU_LOGICAL_ID *LogicalIdPtr + ) +{ + + if ((LogicalIdPtr->Revision & (AMD_F10_BL_ALL | AMD_F10_DA_ALL)) != 0) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.h b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.h new file mode 100755 index 0000000000..e3ebc43d54 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/NI/mrnNi.h @@ -0,0 +1,95 @@ +/** + * @file + * + * mrnNi.h + * + * Northbridge Ni Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** + * + * 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. + * + * *************************************************************************** + * + */ + +#ifndef _MRNNI_H_ +#define _MRNNI_H_ + +/*---------------------------------------------------------------------------- + * Mixed (DEFINITIONS AND MACROS / TYPEDEFS, STRUCTURES, ENUMS) + * + *---------------------------------------------------------------------------- + */ +#define _4GB_RJ8 ((UINT32)4 << (30 - 8)) +#define MTRR_VALID 11 + +/*----------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *----------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS, STRUCTURES, ENUMS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * FUNCTIONS PROTOTYPE + * + *---------------------------------------------------------------------------- + */ + +BOOLEAN +MemRecConstructNBBlockNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN OUT MEM_DATA_STRUCT *MemPtr, + IN UINT8 NodeID + ); + +VOID +MemRecNSwitchDctNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Dct + ); + +VOID +MemRecNSwitchChannelNi ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT8 Channel + ); + +#endif /* _MRNNI_H_ */ + + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrn.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrn.c new file mode 100755 index 0000000000..c55243806f --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrn.c @@ -0,0 +1,188 @@ +/** + * @file + * + * mrn.c + * + * Common Northbridge functions for Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem/NB) + * @e \$Revision: 12594 $ @e \$Date: 2009-04-22 11:04:41 -0500 (Wed, 22 Apr 2009) $ + * + **/ +/***************************************************************************** +* +* 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 "cpuFamRegisters.h" +#include "cpuRegisters.h" +#include "cpuFamilyTranslation.h" +#include "mm.h" +#include "mn.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_MRN_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +#define MAX_DCTS_PER_DIE 2 +#define SPLIT_CHANNEL 0x20000000 +#define CHANNEL_SELECT 0x10000000 +#define MAX_DELAYS 9 /* 8 data bytes + 1 ECC byte */ +#define MAX_DIMMS 4 /* 4 DIMMs per channel */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets a bit field from PCI register + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Field name + * + * @return Bit field value + */ + +UINT32 +MemRecNGetBitFieldNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName + ) +{ + return NBPtr->MemRecNCmnGetSetFieldNb (NBPtr, 0, FieldName, 0); +} + + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets a bit field from PCI register + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] FieldName - Field name + * @param[in] Field - Value to be stored in PCT register + * + */ + +VOID +MemRecNSetBitFieldNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BIT_FIELD_NAME FieldName, + IN UINT32 Field + ) +{ + NBPtr->MemRecNCmnGetSetFieldNb (NBPtr, 1, FieldName, Field); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets a delay value a PCI register during training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * + * @return Value read + */ + +UINT32 +MemRecNGetTrainDlyNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar + ) +{ + return NBPtr->MemRecNcmnGetSetTrainDlyNb (NBPtr, 0, TrnDly, DrbnVar, 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets a delay value a PCI register during training + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] TrnDly - type of delay to be set + * @param[in] DrbnVar - encoding of Dimm-Rank-Byte-Nibble to be accessed + * (use either DIMM_BYTE_ACCESS(dimm,byte) or CS_NBBL_ACCESS(cs,nibble) to use this encoding + * @param[in] Field - Value to be programmed + * + */ + +VOID +MemRecNSetTrainDlyNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN TRN_DLY_TYPE TrnDly, + IN DRBN DrbnVar, + IN UINT16 Field + ) +{ + NBPtr->MemRecNcmnGetSetTrainDlyNb (NBPtr, 1, TrnDly, DrbnVar, Field); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrndct.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrndct.c new file mode 100755 index 0000000000..ee0e54a4b4 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrndct.c @@ -0,0 +1,621 @@ +/** + * @file + * + * mrndct.c + * + * Northbridge common DCT support for Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem/NB) + * @e \$Revision: 6781 $ @e \$Date: 2008-07-17 12:11:08 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "OptionMemory.h" +#include "PlatformMemoryConfiguration.h" +#include "Ids.h" +#include "cpuFamRegisters.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mru.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_MRNDCT_FILECODE +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +#define RECDEF_DRAM_CONTROL_REG 0x320C2A06 +#define RECDEF_DRAM_MRSREG 0x000400A4 +#define RECDEF_DRAM_TIMING_LO 0x000A0092 +#define RECDEF_DRAM_TIMING_HI 0xB6D218FF +#define RECDEF_CSMASK_REG 0x00083FE0 +#define RECDEF_DRAM_CONFIG_LO_REG 0x00000000 +#define RECDEF_DRAM_CONFIG_HI_REG 0x1F48010B +#define RECDEF_DRAM_BASE_REG 0x00000003 + + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +VOID +STATIC +MemRecTCtlOnDimmMirrorNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BOOLEAN SetFlag + ); + +VOID +STATIC +MemRecNSwapBitsNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ); + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function programs the memory controller with configuration parameters + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_ERROR may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred + */ + +BOOLEAN +MemRecNAutoConfigNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 Dimm; + UINT8 Dct; + UINT32 RegValue; + UINT8 ChipSel; + UINT32 CSBase; + DCT_STRUCT *DCTPtr; + CH_DEF_STRUCT *ChannelPtr; + + Dct = NBPtr->Dct; + DCTPtr = NBPtr->DCTPtr; + ChannelPtr = NBPtr->ChannelPtr; + + //Prepare variables for future usage. + for (Dimm = 0; Dimm < MAX_DIMMS_PER_CHANNEL; Dimm++) { + if ((ChannelPtr->ChDimmValid & (UINT8) 1 << Dimm) != 0) { + DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2); + if (((ChannelPtr->DimmDrPresent & (UINT8) 1 << Dimm) == 0) && ((ChannelPtr->DimmQrPresent & (UINT8) 1 << Dimm) == 0)) { + continue; + } else { + DCTPtr->Timings.CsPresent |= (UINT16) 1 << (Dimm * 2 + 1); + } + } + } + + Dimm = NBPtr->DimmToBeUsed; + + //Temporarily set all CS Base/Limit registers (corresponding to Dimms exist on a channel) with 256MB size for WL training. + CSBase = 0; + for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) { + if (DCTPtr->Timings.CsPresent & (UINT8) 1 << ChipSel) { + + CSBase &= (UINT32) ~0x08; //Clear OnDimmMirror bit. + if (((ChipSel & 1) != 0) && ((ChannelPtr->DimmMirrorPresent & (UINT8) 1 << (ChipSel >> 1)) != 0)) { + CSBase |= (UINT32) 0x08; //Set OnDimmMirror bit. + } + MemRecNSetBitFieldNb (NBPtr, (BFCSBaseAddr0Reg + ChipSel), (CSBase | 0x01)); + CSBase += 0x100000; + if ((ChipSel & 1) == 0) { + MemRecNSetBitFieldNb (NBPtr, (BFCSMask0Reg + (ChipSel >> 1)), RECDEF_CSMASK_REG); + } + } + } + MemRecNSetBitFieldNb (NBPtr, BFDramBaseReg0, RECDEF_DRAM_BASE_REG); + MemRecNSetBitFieldNb (NBPtr, BFDramLimitReg0, 0x70000); + + // Disable the other DCT + NBPtr->MemRecNSwitchDctNb (NBPtr, Dct ^ 0x01); + MemRecNSetBitFieldNb (NBPtr, BFDisDramInterface, 1); + NBPtr->MemRecNSwitchDctNb (NBPtr, Dct); + if (Dct != 0) { + // If DCT 1, set DctSelBase registers + MemRecNSetBitFieldNb (NBPtr, BFDctSelBaseAddrReg, 0x00000003); + MemRecNSetBitFieldNb (NBPtr, BFDctSelBaseOffsetReg, 0x00000000); + } + + MemRecNSetBitFieldNb (NBPtr, BFDramBankAddrReg, 0x00001111); + + // Set timing registers + MemRecNSetBitFieldNb (NBPtr, BFDramTimingLoReg, RECDEF_DRAM_TIMING_LO); + MemRecNSetBitFieldNb (NBPtr, BFDramTimingHiReg, RECDEF_DRAM_TIMING_HI); + MemRecNSetBitFieldNb (NBPtr, BFDramMRSReg, RECDEF_DRAM_MRSREG); + MemRecNSetBitFieldNb (NBPtr, BFDramControlReg, RECDEF_DRAM_CONTROL_REG); + + // Set DRAM Config Low Register + RegValue = RECDEF_DRAM_CONFIG_LO_REG; + // Set x4Dimm based on DIMM type + if ((NBPtr->ChannelPtr->Dimmx4Present & ((UINT8) 1 << Dimm)) != 0) { + RegValue |= ((UINT32) 1 << (Dimm + 12)); + } + // If not registered, set unbuffered DIMM + if (!(NBPtr->ChannelPtr->RegDimmPresent & ((UINT8) 1 << Dimm))) { + RegValue |= ((UINT32) 1 << 16); + } + MemRecNSetBitFieldNb (NBPtr, BFDramConfigLoReg, RegValue); + + // Set DRAM Config High Register + RegValue = RECDEF_DRAM_CONFIG_HI_REG; + MemRecNSetBitFieldNb (NBPtr, BFDramConfigHiReg, RegValue); + + //====================================================================== + // Build Dram Config Misc Register Value + //====================================================================== + // + if ((NBPtr->ChannelPtr->RegDimmPresent != 0) && (NBPtr->ChannelPtr->TechType == DDR3_TECHNOLOGY)) { + MemRecNSetBitFieldNb (NBPtr, BFSubMemclkRegDly, 1); + } + MemRecNSetBitFieldNb (NBPtr, BFOdtSwizzle, 1); + + return TRUE; +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function gets platform specific config/timing values from the interface layer and + * programs them into DCT. + * + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return TRUE - An Error value lower than AGESA_ERROR may have occurred + * @return FALSE - An Error value greater than or equal to AGESA_ERROR may have occurred + */ + +BOOLEAN +MemRecNPlatformSpecNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 MaxDimmPerCH; + UINT32 AddrTmgValue; + UINT32 DrvStrValue; + UINT8 *DimmsPerChPtr; + CH_DEF_STRUCT *ChannelPtr; + + ChannelPtr = NBPtr->ChannelPtr; + DimmsPerChPtr = MemRecFindPSOverrideEntry (NBPtr->RefPtr->PlatformMemoryConfiguration, PSO_MAX_DIMMS, 0, ChannelPtr->ChannelID); + if (DimmsPerChPtr != NULL) { + MaxDimmPerCH = *DimmsPerChPtr; + } else { + MaxDimmPerCH = 2; + } + + if (ChannelPtr->RegDimmPresent) { + if (MaxDimmPerCH == 2) { + DrvStrValue = 0x20223222; + AddrTmgValue = 0; + if ((ChannelPtr->Dimms == 1) && (ChannelPtr->DimmQrPresent == 0)) { + DrvStrValue = 0x20113222; + } + } else if (MaxDimmPerCH == 3) { + DrvStrValue = 0x20223222; + AddrTmgValue = 0; + if ((ChannelPtr->Dimms == 1) && (ChannelPtr->DimmQrPresent == 0)) { + DrvStrValue = 0x20113222; + } else if (ChannelPtr->Dimms == 3) { + AddrTmgValue = 0x00380038; + } + } else { + DrvStrValue = 0x20223222; + AddrTmgValue = 0; + if (ChannelPtr->Dimms >= 3) { + AddrTmgValue = 0x002F0000; + } else if (ChannelPtr->Dimms == 1) { + DrvStrValue = 0x20113222; + } + } + } else { + if (ChannelPtr->Dimms == 2) { + DrvStrValue = 0x20223323; + AddrTmgValue = 0x00390039; + } else { + DrvStrValue = 0x20113222; + AddrTmgValue = 0; + if ((ChannelPtr->Dimms == 1) && (ChannelPtr->Loads >= 16)) { + AddrTmgValue = 0x003B0000; + } + } + } + MemRecNSetBitFieldNb (NBPtr, BFODCControl, DrvStrValue); + MemRecNSetBitFieldNb (NBPtr, BFAddrTmgControl, AddrTmgValue); + return TRUE; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function reads MemClkFreqVal bit to see if the DIMMs are present in this node. + * If the DIMMs are present then set the DRAM Enable bit for this node. + * + * Setting dram init starts up the DCT state machine, initializes the + * dram devices with MRS commands, and kicks off any + * HW memory clear process that the chip is capable of. The sooner + * that dram init is set for all nodes, the faster the memory system + * initialization can complete. Thus, the init loop is unrolled into + * two loops so as to start the processes for non BSP nodes sooner. + * This procedure will not wait for the process to finish. Synchronization is + * handled elsewhere. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNStartupDCTNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // 1. Ensure F2x[1, 0]9C_x08[DisAutoComp] = 1. + // 2. BIOS waits 5 us for the disabling of the compensation engine to complete. + // ------- Done in InitPhyComp_Nb ------- + // + MemRecNSetBitFieldNb (NBPtr, BFDisAutoComp, 1); + MemRecUWait10ns (500, NBPtr->MemPtr); + + //MemRecNSetBitFieldNb (NBPtr, BFInitDram, 1); // HW Dram init + AGESA_TESTPOINT (TpProcMemDramInit, &(NBPtr->MemPtr->StdHeader)); + NBPtr->TechPtr->DramInit (NBPtr->TechPtr); + + // 7. Program F2x[1, 0]9C_x08[DisAutoComp] = 0. + // 8. BIOS must wait 750 us for the phy compensation engine + // to reinitialize. + // + MemRecNSetBitFieldNb (NBPtr, BFDisAutoComp, 0); + MemRecUWait10ns (75000, NBPtr->MemPtr); + + while (MemRecNGetBitFieldNb (NBPtr, BFDramEnabled) == 0); +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the maximum round-trip latency in the system from the processor to the DRAM + * devices and back. + + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] MaxRcvEnDly - Maximum receiver enable delay value + * + */ + +VOID +MemRecNSetMaxLatencyNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN UINT16 MaxRcvEnDly + ) +{ + UINT16 SubTotal; + + AGESA_TESTPOINT (TpProcMemRcvrCalcLatency, &(NBPtr->MemPtr->StdHeader)); + + // Multiply the CAS Latency by two to get a number of 1/2 MEMCLKs UINTs. + SubTotal = 6 * 2; + + // If registered DIMMs are being used then add 1 MEMCLK to the sub-total. + if (MemRecNGetBitFieldNb (NBPtr, BFUnBuffDimm) == 0) { + SubTotal += 2; + } + + // if (AddrCmdSetup || CsOdtSetup || CkeSetup) then K := K + 2; + SubTotal += 2; + + // If the F2x[1, 0]78[RdPtrInit] field is 4, 5, 6 or 7 MEMCLKs, + // then add 4, 3, 2, or 1 MEMCLKs, respectively to the sub-total. + // + SubTotal += 8 - 5; + + // Add the maximum (worst case) delay value of DqsRcvEnGrossDelay + // that exists across all DIMMs and byte lanes. + // + SubTotal += MaxRcvEnDly >> 5; + + // Add 5.5 to the sub-total. 5.5 represents part of the processor + // specific constant delay value in the DRAM clock domain. + // + SubTotal += 5; // add 5.5 1/2MemClk + + // Convert the sub-total (in 1/2 MEMCLKs) to northbridge clocks (NCLKs) + // as follows (assuming DDR400 and assuming that no P-state or link speed + // changes have occurred). + // + // Simplified formula: + // SubTotal *= (Fn2xD4[NBFid]+4)/4 + // + SubTotal = SubTotal * ((UINT16) MemRecNGetBitFieldNb (NBPtr, BFNbFid) + 4); + SubTotal /= 4; + + // Add 5 NCLKs to the sub-total. 5 represents part of the processor + // specific constant value in the northbridge clock domain. + // + SubTotal += 5; + + // Program the F2x[1, 0]78[MaxRdLatency] register with the total delay value + MemRecNSetBitFieldNb (NBPtr, BFMaxLatency, SubTotal); +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * Set Dram ODT for mission mode and write leveling mode. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] OdtMode - Mission mode or write leveling mode + * @param[in] ChipSelect - Chip select number + * @param[in] TargetCS - Chip select number that is being trained + * + */ + +VOID +MemRecNSetDramOdtNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN ODT_MODE OdtMode, + IN UINT8 ChipSelect, + IN UINT8 TargetCS + ) +{ + UINT8 Dimms; + UINT8 DramTerm; + UINT8 DramTermDyn; + BOOLEAN IsDualRank; + + Dimms = NBPtr->ChannelPtr->Dimms; + IsDualRank = (NBPtr->DCTPtr->Timings.CsPresent & (ChipSelect + 1)) ? TRUE : FALSE; + + if (OdtMode == WRITE_LEVELING_MODE) { + DramTermDyn = 0; // Disabled + + if (ChipSelect & 1) { + DramTerm = 0; // Disabled + } else if (Dimms == 1) { + DramTerm = 1; // 60 Ohms + } else { + DramTerm = 3; // 40 Ohms + } + + if (ChipSelect == TargetCS) { + if (Dimms == 2) { + DramTerm = 2; // 120 Ohms + } else if (IsDualRank) { + DramTerm = 0; // Disabled + } + + // Program WrLvOdt + MemRecNSetBitFieldNb (NBPtr, BFWrLvOdt, 0x0F); + } else if (ChipSelect == (TargetCS + 1)) { + if (Dimms == 1) { + DramTerm = 1; // 60 Ohms + } + } + } else { + // Dram nominal termination + if (Dimms == 1) { + DramTerm = 1; // 60 Ohms + } else { + DramTerm = 3; // 40 Ohms + } + + // Dram dynamic termination + if (Dimms < 2) { + DramTermDyn = 0; // Disabled + } else { + DramTermDyn = 2; // 120 Ohms + } + } + MemRecNSetBitFieldNb (NBPtr, BFDramTerm, DramTerm); + MemRecNSetBitFieldNb (NBPtr, BFDramTermDyn, DramTermDyn); +} + +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sends an MRS command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNSendMrsCmdNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + BOOLEAN ClearODM; + ClearODM = FALSE; + if (NBPtr->IsSupported[CheckClearOnDimmMirror]) { + ClearODM = FALSE; + if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F10_C0) != 0) { + if (NBPtr->IsSupported[CheckClearOnDimmMirror]) { + if (MemRecNGetBitFieldNb (NBPtr, BFEnDramInit) == 0) { + // For C0, if EnDramInit bit is cleared, ODM needs to be cleared before sending MRS + MemRecTCtlOnDimmMirrorNb (NBPtr, FALSE); + ClearODM = TRUE; + } + } + } + } + + MemRecNSwapBitsNb (NBPtr); + + IDS_HDT_CONSOLE ("\t\t\tCS%d MR%d %04x\n", + (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 20) & 0xF, + (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 16) & 0xF, + (MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg) & 0xFFFF)); + + // 1.Set SendMrsCmd=1 + MemRecNSetBitFieldNb (NBPtr, BFSendMrsCmd, 1); + + // 2.Wait for SendMrsCmd=0 + while (MemRecNGetBitFieldNb (NBPtr, BFSendMrsCmd)) {} + + if (NBPtr->IsSupported[CheckClearOnDimmMirror]) { + if (ClearODM) { + // Restore ODM if necessary + MemRecTCtlOnDimmMirrorNb (NBPtr, TRUE); + } + } +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sends the ZQCL command + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNSendZQCmdNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + // 1.Program MrsAddress[10]=1 + MemRecNSetBitFieldNb (NBPtr, BFMrsAddress, (UINT32) 1 << 10); + + // 2.Set SendZQCmd=1 + MemRecNSetBitFieldNb (NBPtr, BFSendZQCmd, 1); + + // 3.Wait for SendZQCmd=0 + while (MemRecNGetBitFieldNb (NBPtr, BFSendZQCmd)) {} + + // 4.Wait 512 MEMCLKs + MemRecUWait10ns (128, NBPtr->MemPtr); // 512*2.5ns=1280, wait 1280ns +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function disables/enables F2x[1, 0][5C:40][OnDimmMirror] + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * @param[in] SetFlag - Enable or disable flag - TRUE - Enable, FALSE - DISABLE + * + */ + +VOID +STATIC +MemRecTCtlOnDimmMirrorNb ( + IN OUT MEM_NB_BLOCK *NBPtr, + IN BOOLEAN SetFlag + ) +{ + UINT8 Chipsel; + UINT32 CSBaseAddrReg; + + for (Chipsel = 0; Chipsel < MAX_CS_PER_CHANNEL; Chipsel += 2) { + CSBaseAddrReg = MemRecNGetBitFieldNb (NBPtr, BFCSBaseAddr1Reg + Chipsel); + if ((CSBaseAddrReg & 1) == 1) { + if (SetFlag && ((NBPtr->ChannelPtr->DimmMirrorPresent & ((UINT8) 1 << (Chipsel >> 1))) != 0)) { + CSBaseAddrReg |= ((UINT32) 1 << BFOnDimmMirror); + } else { + CSBaseAddrReg &= ~((UINT32) 1 << BFOnDimmMirror); + } + MemRecNSetBitFieldNb (NBPtr, BFCSBaseAddr1Reg + Chipsel, CSBaseAddrReg); + } + } +} +/* -----------------------------------------------------------------------------*/ +/** + * + * + * This function swaps bits for OnDimmMirror support + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +STATIC +MemRecNSwapBitsNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + UINT8 ChipSel; + UINT32 MRSReg; + + ChipSel = (UINT8) MemRecNGetBitFieldNb (NBPtr, BFMrsChipSel); + if ((ChipSel & 1) != 0) { + MRSReg = MemRecNGetBitFieldNb (NBPtr, BFDramInitRegReg); + if ((NBPtr->ChannelPtr->DimmMirrorPresent & (UINT8) 1 << (ChipSel >> 1)) != 0) { + MRSReg = (MRSReg & 0xFFFCFE07) | ((MRSReg&0x100A8) << 1) | ((MRSReg&0x20150) >> 1); + MemRecNSetBitFieldNb (NBPtr, BFDramInitRegReg, MRSReg); + } + } +} diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrnmct.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrnmct.c new file mode 100755 index 0000000000..6c0432a853 --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrnmct.c @@ -0,0 +1,295 @@ +/** + * @file + * + * mrnmct.c + * + * Northbridge Common MCT supporting functions Recovery + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Proc/Recovery/Mem/NB) + * @e \$Revision: 6783 $ @e \$Date: 2008-07-17 13:07:51 -0500 (Thu, 17 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "mrport.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "cpuFamilyTranslation.h" +#include "cpuCacheInit.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_MRNMCT_FILECODE + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + + +/*---------------------------------------------------------------------------- + * EXPORTED FUNCTIONS + * + *---------------------------------------------------------------------------- + */ + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function is the Recovery memory configuration function for Nb DDR3 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + * @return AGESA_STATUS + * - AGESA_ALERT + * - AGESA_FATAL + * - AGESA_SUCCESS + * - AGESA_WARNING + */ + +AGESA_STATUS +MemRecNMemInitNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + AGESA_STATUS Status; + MEM_TECH_BLOCK *TechPtr; + + TechPtr = NBPtr->TechPtr; + + MemRecNInitializeMctNb (NBPtr); + + if (NBPtr->IsSupported[DramModeBeforeDimmPres]) { + TechPtr->SetDramMode (TechPtr); + } + + Status = AGESA_FATAL; + if (TechPtr->DimmPresence (TechPtr)) { + + if (NBPtr->IsSupported[DramModeAfterDimmPres]) { + TechPtr->SetDramMode (TechPtr); + } + + if (MemRecNAutoConfigNb (NBPtr)) { + + AGESA_TESTPOINT (TpProcMemPlatformSpecificConfig, &(NBPtr->MemPtr->StdHeader)); + if (MemRecNPlatformSpecNb (NBPtr)) { + AGESA_TESTPOINT (TpProcMemStartDcts, &(NBPtr->MemPtr->StdHeader)); + MemRecNStartupDCTNb (NBPtr); + + AGESA_TESTPOINT (TpProcMemMtrrConfiguration, &(NBPtr->MemPtr->StdHeader)); + MemRecNCPUMemRecTypingNb (NBPtr); + + AGESA_TESTPOINT (TpProcMemDramTraining, &(NBPtr->MemPtr->StdHeader)); + NBPtr->TrainingFlow (NBPtr); + + Status = AGESA_SUCCESS; + } + } + } + + NBPtr->MemRecNFinalizeMctNb (NBPtr); + + return Status; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets initial values in BUCFG and BUCFG2 + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNInitializeMctNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MEM_DATA_STRUCT *MemPtr; + S_UINT64 SMsr; + + MemPtr = NBPtr->MemPtr; + + LibAmdMsrRead (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + if (SMsr.lo & ((UINT32) 1 << 15)) { + NBPtr->ClToNbFlag = TRUE; + } + SMsr.lo |= (UINT32) 1 << 15; // ClLinesToNbDis + LibAmdMsrWrite (BU_CFG2, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + LibAmdMsrRead (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.hi |= (UINT32) 1 << (48 - 32); // WbEnhWsbDis + LibAmdMsrWrite (BU_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); +} + + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function returns a physical address of a corresponding Chip select + * + * @return Addr - System Address + */ + +UINT32 +MemRecNGetMCTSysAddrNb ( + ) +{ + UINT32 CSBase; + + CSBase = (UINT32) 1 << 21; // 1MB offset to avoid compat area from the base address. + if ((CSBase >= (MCT_TRNG_KEEPOUT_START << 8)) && (CSBase <= (MCT_TRNG_KEEPOUT_END << 8))) { + CSBase += (((MCT_TRNG_KEEPOUT_END << 8) - CSBase) + 0x0FFFFF) & 0xFFF00000; + } + + return CSBase; +} + +/* -----------------------------------------------------------------------------*/ +/** + * + * This function runs on the BSP only, it sets the fixed MTRRs for common legacy ranges. + * It sets TOP_MEM and TOM2 and some variable MTRRs with WB Uncacheable type. + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + * + */ + +VOID +MemRecNCPUMemRecTypingNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + S_UINT64 SMsr; + + MEM_DATA_STRUCT *MemPtr; + MemPtr = NBPtr->MemPtr; + + // + //====================================================================== + // Set default values for CPU registers + //====================================================================== + // + + LibAmdMsrRead (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + SMsr.lo |= 0x1C0000; // turn on modification enable bit and + // mtrr enable bits + LibAmdMsrWrite (SYS_CFG, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + SMsr.lo = SMsr.hi = 0x1E1E1E1E; + LibAmdMsrWrite (0x250, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 0 - 512K = WB Mem + LibAmdMsrWrite (0x258, (UINT64 *)&SMsr, &MemPtr->StdHeader); // 512K - 640K = WB Mem + + // + //====================================================================== + // Set TOP_MEM and TOM2 CPU registers + //====================================================================== + // + SMsr.hi = 0; + SMsr.lo = 0x08000000; + LibAmdMsrWrite (TOP_MEM, (UINT64 *)&SMsr, &MemPtr->StdHeader); // TOP_MEM + + // Set FS Base address for later memory accesses + SMsr.lo = 0; + LibAmdMsrWrite (FS_BASE, (UINT64 *)&SMsr, &MemPtr->StdHeader); + + // + //====================================================================== + // Set variable MTRR values + //====================================================================== + // + SMsr.lo = 0x00000006; + LibAmdMsrWrite (0x200, (UINT64 *)&SMsr, &MemPtr->StdHeader); // MTRRPhysBase0 + + SMsr.hi = NBPtr->VarMtrrHiMsk; + SMsr.lo = 0xF8000800; + LibAmdMsrWrite (0x201, (UINT64 *)&SMsr, &MemPtr->StdHeader); // MTRRPhysMask0 + +} + +/*-----------------------------------------------------------------------------*/ +/** + * + * This function returns the upper 32 bits mask for variable MTRR based on + * the CPU_LOGICAL_ID. + * @param[in] *LogicalIdPtr - Pointer to the CPU_LOGICAL_ID + * @param[in] StdHeader - Header for library and services + * + * @return UINT32 - MTRR mask for upper 32 bits + * + */ +UINT32 +MemRecGetVarMtrrHiMsk ( + IN CPU_LOGICAL_ID *LogicalIdPtr, + IN AMD_CONFIG_PARAMS *StdHeader + ) +{ + UINT8 TempNotCare; + CPU_SPECIFIC_SERVICES *FamilySpecificServices; + CACHE_INFO *CacheInfoPtr; + + GetCpuServicesFromLogicalId (LogicalIdPtr, &FamilySpecificServices, StdHeader); + FamilySpecificServices->GetCacheInfo (FamilySpecificServices, &CacheInfoPtr, &TempNotCare, StdHeader); + return (UINT32) (CacheInfoPtr->VariableMtrrMask >> 32); +} +/*---------------------------------------------------------------------------- + * LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ diff --git a/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrntrain3.c b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrntrain3.c new file mode 100755 index 0000000000..9be59a169b --- /dev/null +++ b/src/vendorcode/amd/agesa/f10/Proc/Recovery/Mem/NB/mrntrain3.c @@ -0,0 +1,101 @@ +/** + * @file + * + * mrntrain3.c + * + * Common Recovery Northbridge function for training flow for DDR3 + * + * @xrefitem bom "File Content Label" "Release Content" + * @e project: AGESA + * @e sub-project: (Mem/NB) + * @e \$Revision: 7081 $ @e \$Date: 2008-07-31 01:47:27 -0500 (Thu, 31 Jul 2008) $ + * + **/ +/***************************************************************************** +* +* 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 "OptionMemory.h" +#include "mm.h" +#include "mn.h" +#include "mt.h" +#include "mrt3.h" +#include "Filecode.h" +#define FILECODE PROC_RECOVERY_MEM_NB_MRNTRAIN3_FILECODE +/* features */ + +/*---------------------------------------------------------------------------- + * DEFINITIONS AND MACROS + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * TYPEDEFS AND STRUCTURES + * + *---------------------------------------------------------------------------- + */ + +/*---------------------------------------------------------------------------- + * PROTOTYPES OF LOCAL FUNCTIONS + * + *---------------------------------------------------------------------------- + */ +/* -----------------------------------------------------------------------------*/ +/** + * + * This function sets the training control flow + * The DDR3 mode bit must be set prior to calling this function + * + * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK + */ +VOID +MemNRecTrainingFlowNb ( + IN OUT MEM_NB_BLOCK *NBPtr + ) +{ + MemRecTTrainDQSWriteHw3 (NBPtr->TechPtr); + + MemRecTTrainRcvrEnSw (NBPtr->TechPtr); + + MemRecTTrainDQSPosSw (NBPtr->TechPtr); +} |