Update AMD F14 Agesa to support Rev C0 cpus
[coreboot.git] / src / vendorcode / amd / agesa / f14 / Proc / Mem / NB / ON / mnon.c
blob17a20198cf99f42beec22d9ef24501be100c122d
1 /* $NoKeywords:$ */
2 /**
3 * @file
5 * mnon.c
7 * Common Northbridge functions for ON
9 * @xrefitem bom "File Content Label" "Release Content"
10 * @e project: AGESA
11 * @e sub-project: (Mem/NB/ON)
12 * @e \$Revision: 48511 $ @e \$Date: 2011-03-09 13:53:13 -0700 (Wed, 09 Mar 2011) $
14 **/
16 *****************************************************************************
18 * Copyright (c) 2011, Advanced Micro Devices, Inc.
19 * All rights reserved.
21 * Redistribution and use in source and binary forms, with or without
22 * modification, are permitted provided that the following conditions are met:
23 * * Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * * Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in the
27 * documentation and/or other materials provided with the distribution.
28 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
29 * its contributors may be used to endorse or promote products derived
30 * from this software without specific prior written permission.
32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
33 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
34 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
35 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
36 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
38 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
39 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
40 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 * ***************************************************************************
47 *----------------------------------------------------------------------------
48 * MODULES USED
50 *----------------------------------------------------------------------------
55 #include "AGESA.h"
56 #include "AdvancedApi.h"
57 #include "amdlib.h"
58 #include "Ids.h"
59 #include "OptionMemory.h"
60 #include "mm.h"
61 #include "mn.h"
62 #include "mnon.h"
63 #include "mu.h"
64 #include "merrhdl.h"
65 #include "S3.h"
66 #include "cpuRegisters.h"
67 #include "cpuFamRegisters.h"
68 #include "cpuFamilyTranslation.h"
69 #include "heapManager.h"
70 #include "GeneralServices.h"
71 #include "Filecode.h"
72 #define FILECODE PROC_MEM_NB_ON_MNON_FILECODE
73 /*----------------------------------------------------------------------------
74 * DEFINITIONS AND MACROS
76 *----------------------------------------------------------------------------
78 CONST MEM_FREQ_CHANGE_PARAM FreqChangeParamON = {0x1838, 2, 3, 10, 2, 9, 665, 1000};
79 /*----------------------------------------------------------------------------
80 * TYPEDEFS AND STRUCTURES
82 *----------------------------------------------------------------------------
85 /*----------------------------------------------------------------------------
86 * PROTOTYPES OF LOCAL FUNCTIONS
88 *----------------------------------------------------------------------------
91 /*----------------------------------------------------------------------------
92 * EXPORTED FUNCTIONS
94 *----------------------------------------------------------------------------
97 extern BUILD_OPT_CFG UserOptions;
98 extern PSO_ENTRY DefaultPlatformMemoryConfiguration[];
99 extern OPTION_MEM_FEATURE_NB* memNTrainFlowControl[];
101 /* -----------------------------------------------------------------------------*/
104 * This function initializes the northbridge block
106 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
107 * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
108 * @param[in] *FeatPtr - Pointer to the MEM_FEAT_BLOCK_NB
109 * @param[in] *SharedPtr - Pointer to the MEM_SHARED_DATA
110 * @param[in] NodeID - UINT8 indicating node ID of the NB object.
112 * @retval Boolean indicating that this is the correct memory
113 * controller type for the node number that was passed in.
116 BOOLEAN
117 MemConstructNBBlockON (
118 IN OUT MEM_NB_BLOCK *NBPtr,
119 IN OUT MEM_DATA_STRUCT *MemPtr,
120 IN MEM_FEAT_BLOCK_NB *FeatPtr,
121 IN MEM_SHARED_DATA *SharedPtr,
122 IN UINT8 NodeID
125 INT32 i;
126 DIE_STRUCT *MCTPtr;
127 ALLOCATE_HEAP_PARAMS AllocHeapParams;
130 // Determine if this is the expected NB Type
132 GetLogicalIdOfSocket (MemPtr->DiesPerSystem->SocketId, &(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader));
133 if (!MemNIsIdSupportedON (NBPtr, &(MemPtr->DiesPerSystem->LogicalCpuid))) {
134 return FALSE;
137 NBPtr->MemPtr = MemPtr;
138 NBPtr->RefPtr = MemPtr->ParameterListPtr;
139 NBPtr->SharedPtr = SharedPtr;
141 MCTPtr = MemPtr->DiesPerSystem;
142 NBPtr->MCTPtr = MCTPtr;
143 NBPtr->MCTPtr->NodeId = 0;
144 NBPtr->PciAddr.AddressValue = MCTPtr->PciAddr.AddressValue;
145 NBPtr->VarMtrrHiMsk = GetVarMtrrHiMsk (&(MemPtr->DiesPerSystem->LogicalCpuid), &(MemPtr->StdHeader));
148 // Allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
150 AllocHeapParams.RequestedBufferSize = (sizeof (DCT_STRUCT) + sizeof (CH_DEF_STRUCT) + sizeof (MEM_PS_BLOCK));
151 AllocHeapParams.BufferHandle = GENERATE_MEM_HANDLE (ALLOC_DCT_STRUCT_HANDLE, NodeID, 0, 0);
152 AllocHeapParams.Persist = HEAP_LOCAL_CACHE;
153 if (HeapAllocateBuffer (&AllocHeapParams, &MemPtr->StdHeader) != AGESA_SUCCESS) {
154 PutEventLog (AGESA_FATAL, MEM_ERROR_HEAP_ALLOCATE_FOR_DCT_STRUCT_AND_CH_DEF_STRUCTs, NBPtr->Node, 0, 0, 0, &MemPtr->StdHeader);
155 SetMemError (AGESA_FATAL, MCTPtr);
156 ASSERT(FALSE); // Could not allocate buffer for DCT_STRUCTs and CH_DEF_STRUCTs
157 return FALSE;
160 MCTPtr->Dct = 0;
161 MCTPtr->DctCount = MAX_DCTS_PER_NODE_ON;
162 MCTPtr->DctData = (DCT_STRUCT *) AllocHeapParams.BufferPtr;
163 AllocHeapParams.BufferPtr += sizeof (DCT_STRUCT);
164 MCTPtr->DctData->ChannelCount = 1;
165 MCTPtr->DctData->ChData = (CH_DEF_STRUCT *) AllocHeapParams.BufferPtr;
166 AllocHeapParams.BufferPtr += sizeof (CH_DEF_STRUCT);
167 NBPtr->PSBlock = (MEM_PS_BLOCK *) AllocHeapParams.BufferPtr;
170 // Initialize Socket List
172 *(MemPtr->SocketList[MCTPtr->SocketId].ChannelPtr) = MCTPtr->DctData->ChData;
173 *(MemPtr->SocketList[MCTPtr->SocketId].TimingsPtr) = &(MCTPtr->DctData->Timings);
174 MCTPtr->DctData->ChData->ChannelID = 0;
177 // Initialize NB block member variables
180 NBPtr->DCTPtr = NBPtr->MCTPtr->DctData;
181 NBPtr->DctCachePtr = NBPtr->DctCache;
182 NBPtr->PsPtr = NBPtr->PSBlock;
183 NBPtr->ChannelPtr = NBPtr->DCTPtr->ChData;
185 MemNInitNBRegTableON (NBPtr, NBPtr->NBRegTable);
186 NBPtr->Node = 0;
187 NBPtr->Dct = 0;
188 NBPtr->Channel = 0;
189 NBPtr->DctCount = MAX_DCTS_PER_NODE_ON;
190 NBPtr->ChannelCount = MAX_CHANNELS_PER_DCT_ON;
191 NBPtr->NodeCount = MAX_NODES_SUPPORTED_ON;
192 NBPtr->Ganged = FALSE;
193 NBPtr->PosTrnPattern = POS_PATTERN_256B;
194 NBPtr->MemCleared = FALSE;
195 NBPtr->StartupSpeed = DDR800_FREQUENCY;
196 NBPtr->RcvrEnDlyLimit = 0xFF;
197 NBPtr->DefDctSelIntLvAddr = 3;
198 NBPtr->FreqChangeParam = (MEM_FREQ_CHANGE_PARAM *) &FreqChangeParamON;
199 NBPtr->NbFreqChgState = 0;
201 LibAmdMemFill (NBPtr->DctCache, 0, sizeof (NBPtr->DctCache), &NBPtr->MemPtr->StdHeader);
203 for (i = 0; i < EnumSize; i++) {
204 NBPtr->IsSupported[i] = FALSE;
207 for (i = 0; i < NumberOfHooks; i++) {
208 NBPtr->FamilySpecificHook[i] = (BOOLEAN (*) (MEM_NB_BLOCK*, VOID*)) memDefTrue;
211 FeatPtr->InitHwRxEn (NBPtr);
214 NBPtr->SwitchDCT = (VOID (*) (MEM_NB_BLOCK*, UINT8)) memDefRet;
215 NBPtr->SwitchChannel = (VOID (*) (MEM_NB_BLOCK*, UINT8)) memDefRet;
216 NBPtr->GetBitField = MemNGetBitFieldNb;
217 NBPtr->SetBitField = MemNSetBitFieldNb;
218 NBPtr->SetMaxLatency = MemNSetMaxLatencyON;
219 NBPtr->getMaxLatParams = MemNGetMaxLatParamsClientON;
220 NBPtr->InitializeMCT = (BOOLEAN (*) (MEM_NB_BLOCK*)) memDefTrue;
221 NBPtr->FinalizeMCT = MemNFinalizeMctON;
222 NBPtr->SendMrsCmd = MemNSendMrsCmdON;
223 NBPtr->sendZQCmd = MemNSendZQCmdNb;
224 NBPtr->WritePattern = MemNWritePatternON;
225 NBPtr->ReadPattern = MemNReadPatternON;
226 NBPtr->GenHwRcvEnReads = (VOID (*) (MEM_NB_BLOCK*, UINT32)) memDefRet;
228 NBPtr->CompareTestPattern = MemNCompareTestPatternNb;
229 NBPtr->InsDlyCompareTestPattern = MemNInsDlyCompareTestPatternNb;
230 NBPtr->InitMCT = MemNInitMCTNb;
231 NBPtr->StitchMemory = MemNStitchMemoryON;
232 NBPtr->AutoConfig = MemNAutoConfigON;
233 NBPtr->PlatformSpec = MemNPlatformSpecUnb;
234 NBPtr->DisableDCT = MemNDisableDCTNb;
235 NBPtr->StartupDCT = MemNStartupDCTUnb;
236 NBPtr->SyncTargetSpeed = MemNSyncTargetSpeedNb;
237 NBPtr->MemNCapSpeedBatteryLife = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
238 NBPtr->ChangeFrequency = MemNChangeFrequencyUnb;
239 NBPtr->RampUpFrequency = MemNRampUpFrequencyNb;
240 NBPtr->ChangeNbFrequency = MemNChangeNbFrequencyNb;
241 NBPtr->ProgramNbPsDependentRegs = MemNProgramNbPstateDependentRegistersClientNb;
242 NBPtr->ProgramCycTimings = MemNProgramCycTimingsClientNb;
243 NBPtr->SyncDctsReady = (BOOLEAN (*) (MEM_NB_BLOCK *)) memDefTrue;
244 NBPtr->HtMemMapInit = MemNHtMemMapInitON;
245 NBPtr->SyncAddrMapToAllNodes = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
246 NBPtr->CpuMemTyping = MemNCPUMemTypingNb;
247 NBPtr->UMAMemTyping = MemNUMAMemTypingNb;
248 NBPtr->BeforeDqsTraining = MemNBeforeDQSTrainingON;
249 NBPtr->AfterDqsTraining = MemNAfterDQSTrainingON;
250 NBPtr->OtherTiming = MemNOtherTimingON;
251 NBPtr->GetSocketRelativeChannel = MemNGetSocketRelativeChannelNb;
252 NBPtr->TechBlockSwitch = MemNTechBlockSwitchON;
253 NBPtr->SetEccSymbolSize = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
254 NBPtr->TrainingFlow = (VOID (*) (MEM_NB_BLOCK *)) memNTrainFlowControl[DDR3_TRAIN_FLOW];
255 NBPtr->MinDataEyeWidth = MemNMinDataEyeWidthNb;
256 NBPtr->PollBitField = MemNPollBitFieldNb;
257 NBPtr->BrdcstCheck = MemNBrdcstCheckON;
258 NBPtr->BrdcstSet = MemNSetBitFieldNb;
259 NBPtr->GetTrainDly = MemNGetTrainDlyNb;
260 NBPtr->SetTrainDly = MemNSetTrainDlyNb;
261 NBPtr->PhyFenceTraining = MemNPhyFenceTrainingUnb;
262 NBPtr->GetSysAddr = MemNGetMCTSysAddrNb;
263 NBPtr->RankEnabled = MemNRankEnabledNb;
264 NBPtr->MemNCmnGetSetFieldNb = MemNCmnGetSetFieldON;
265 NBPtr->MemNBeforeDramInitNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
266 NBPtr->MemNBeforePlatformSpecNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
267 NBPtr->MemNInitPhyComp = MemNInitPhyCompClientNb;
268 NBPtr->MemNcmnGetSetTrainDly = MemNcmnGetSetTrainDlyClientNb;
269 NBPtr->MemPPhyFenceTrainingNb = (VOID (*) (MEM_NB_BLOCK *)) memDefRet;
270 NBPtr->MemNPlatformSpecificFormFactorInitNb = MemNPlatformSpecificFormFactorInitON;
271 NBPtr->MemNPFenceAdjustNb = (VOID (*) (MEM_NB_BLOCK *, UINT16 *)) memDefRet;
272 NBPtr->GetTrainDlyParms = MemNGetTrainDlyParmsClientNb;
273 NBPtr->TrainingPatternInit = MemNTrainingPatternInitNb;
274 NBPtr->TrainingPatternFinalize = MemNTrainingPatternFinalizeNb;
275 NBPtr->GetApproximateWriteDatDelay = MemNGetApproximateWriteDatDelayNb;
276 NBPtr->CSPerChannel = MemNCSPerChannelON;
277 NBPtr->CSPerDelay = MemNCSPerDelayNb;
278 NBPtr->FlushPattern = MemNFlushPatternNb;
279 NBPtr->GetUmaSize = MemNGetUmaSizeON;
280 NBPtr->GetMemClkFreqId = MemNGetMemClkFreqIdClientNb;
281 NBPtr->EnableSwapIntlvRgn = (VOID (*) (MEM_NB_BLOCK *, UINT32, UINT32)) memDefRet;
282 NBPtr->ChangeNbFrequencyWrap = MemNChangeNbFrequencyWrapON;
283 NBPtr->WaitXMemClks = MemNWaitXMemClksNb;
284 NBPtr->MemNGetDramTerm = MemNGetDramTermNb;
285 NBPtr->MemNGetDynDramTerm = MemNGetDynDramTermNb;
286 NBPtr->MemNGetMR0CL = MemNGetMR0CLNb;
287 NBPtr->MemNGetMR0WR = MemNGetMR0WRNb;
288 NBPtr->MemNGetMR2CWL = MemNGetMR2CWLNb;
289 NBPtr->AllocateC6Storage = MemNAllocateC6StorageClientNb;
291 NBPtr->IsSupported[SetDllShutDown] = TRUE;
292 NBPtr->IsSupported[CheckPhyFenceTraining] = TRUE;
293 NBPtr->IsSupported[CheckSendAllMRCmds] = TRUE;
294 NBPtr->IsSupported[CheckFindPSDct] = TRUE;
295 NBPtr->IsSupported[CheckODTControls] = TRUE;
296 NBPtr->IsSupported[FenceTrnBeforeDramInit] = TRUE;
297 NBPtr->IsSupported[WLSeedAdjust] = TRUE;
298 NBPtr->IsSupported[ReverseMaxRdLatTrain] = TRUE;
299 NBPtr->IsSupported[DramSrHys] = TRUE;
300 NBPtr->IsSupported[CheckMaxDramRate] = TRUE;
301 NBPtr->IsSupported[AdjustTwr] = TRUE;
302 NBPtr->IsSupported[UnifiedNbFence] = TRUE;
303 NBPtr->IsSupported[ChannelPDMode] = TRUE; // Erratum 435
304 if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F14_ON_C0) != 0) {
305 NBPtr->IsSupported[AdjustTrc] = TRUE;
308 NBPtr->FamilySpecificHook[OverrideRcvEnSeed] = MemNOverrideRcvEnSeedON;
309 NBPtr->FamilySpecificHook[BeforePhyFenceTraining] = MemNBeforePhyFenceTrainingClientNb;
310 NBPtr->FamilySpecificHook[AdjustTxpdll] = MemNAdjustTxpdllClientNb;
311 if ((NBPtr->MCTPtr->LogicalCpuid.Revision & AMD_F14_ON_Cx) == 0) {
312 // Do not do phase B enforcement for Rev C
313 NBPtr->FamilySpecificHook[ForceRdDqsPhaseB] = MemNForceRdDqsPhaseBON;
315 NBPtr->FamilySpecificHook[SetDqsODT] = MemNSetDqsODTON;
316 NBPtr->FamilySpecificHook[ResetRxFifoPtr] = MemNResetRxFifoPtrON;
317 NBPtr->FamilySpecificHook[BfAfExcludeDimm] = MemNBfAfExcludeDimmClientNb;
318 NBPtr->FamilySpecificHook[BeforeMemClkFreqVal] = MemNBeforeMemClkFreqValON;
320 FeatPtr->InitCPG (NBPtr);
321 FeatPtr->InitEarlySampleSupport (NBPtr);
322 NBPtr->FeatPtr = FeatPtr;
324 // Calculate SPD Offsets per channel and assign pointers
325 // to the data.
327 NBPtr->MCTPtr->DctData->ChData->SpdPtr = MemPtr->SpdDataStructure;
329 return TRUE;
332 /* -----------------------------------------------------------------------------*/
335 * This function initializes the default values in the MEM_DATA_STRUCT
337 * @param[in,out] *MemPtr - Pointer to the MEM_DATA_STRUCT
339 * @retval None
341 VOID
342 MemNInitDefaultsON (
343 IN OUT MEM_DATA_STRUCT *MemPtr
346 UINT8 Socket;
347 MEM_PARAMETER_STRUCT *RefPtr;
348 AGESA_TESTPOINT (TpProcMemBeforeMemDataInit, &(MemPtr->StdHeader));
349 ASSERT (MemPtr != NULL);
350 RefPtr = MemPtr->ParameterListPtr;
352 // Memory Map/Mgt.
353 // Mask Bottom IO with 0xF8 to force hole size to have granularity of 128MB
354 RefPtr->BottomIo = 0xE0;
355 RefPtr->UmaMode = UserOptions.CfgUmaMode;
356 RefPtr->UmaSize = UserOptions.CfgUmaSize;
357 RefPtr->MemHoleRemapping = TRUE;
359 // Dram Timing
360 RefPtr->UserTimingMode = UserOptions.CfgTimingModeSelect;
361 RefPtr->MemClockValue = UserOptions.CfgMemoryClockSelect;
362 for (Socket = 0; Socket < MAX_SOCKETS_SUPPORTED; Socket++) {
363 MemPtr->SocketList[Socket].ChannelPtr[0] = NULL;
364 MemPtr->SocketList[Socket].TimingsPtr[0] = NULL;
367 // Memory Clear
368 RefPtr->EnableMemClr = TRUE;
370 // TableBasedAlterations
371 RefPtr->TableBasedAlterations = NULL;
373 // Platform config table
374 RefPtr->PlatformMemoryConfiguration = DefaultPlatformMemoryConfiguration;
376 // Memory Restore
377 RefPtr->MemRestoreCtl = FALSE;
378 RefPtr->SaveMemContextCtl = FALSE;
379 AmdS3ParamsInitializer (&RefPtr->MemContext);
381 // Dram Configuration
382 RefPtr->EnableBankIntlv = UserOptions.CfgMemoryEnableBankInterleaving;
383 RefPtr->EnableNodeIntlv = FALSE;
384 RefPtr->EnableChannelIntlv = FALSE;
385 RefPtr->EnableBankSwizzle = UserOptions.CfgBankSwizzle;
386 RefPtr->EnableParity = FALSE;
387 RefPtr->EnableOnLineSpareCtl = FALSE;
389 // Dram Power
390 RefPtr->EnablePowerDown = UserOptions.CfgMemoryPowerDown;
392 // ECC
393 RefPtr->EnableEccFeature = FALSE;
396 /*-----------------------------------------------------------------------------*/
399 * This function writes training pattern
400 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
401 * @param[in] Pattern[] - Pattern to write
402 * @param[in] Address - System Address [47:16]
403 * @param[in] ClCount - Number of cache lines
407 VOID
408 MemNWritePatternON (
409 IN OUT MEM_NB_BLOCK *NBPtr,
410 IN UINT32 Address,
411 IN UINT8 Pattern[],
412 IN UINT16 ClCount
415 Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr);
416 MemUWriteCachelines (Address, Pattern, ClCount);
419 /*-----------------------------------------------------------------------------*/
422 * This function reads training pattern
423 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
424 * @param[in] Buffer[] - Buffer to fill
425 * @param[in] Address - System Address [47:16]
426 * @param[in] ClCount - Number of cache lines
430 VOID
431 MemNReadPatternON (
432 IN OUT MEM_NB_BLOCK *NBPtr,
433 IN UINT8 Buffer[],
434 IN UINT32 Address,
435 IN UINT16 ClCount
438 Address = MemUSetUpperFSbase (Address, NBPtr->MemPtr);
439 MemUReadCachelines (Buffer, Address, ClCount);
442 /* -----------------------------------------------------------------------------*/
445 * This function initiates DQS training for Client NB
447 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
451 BOOLEAN
452 memNEnableTrainSequenceON (
453 IN OUT MEM_NB_BLOCK *NBPtr
456 BOOLEAN Retval;
457 Retval = TRUE;
458 if (!MemNIsIdSupportedON (NBPtr, &(NBPtr->MemPtr->DiesPerSystem[NBPtr->MCTPtr->NodeId].LogicalCpuid))) {
459 Retval = FALSE;
461 return Retval;