7 * Northbridge DCT support for Hydra
9 * @xrefitem bom "File Content Label" "Release Content"
11 * @e sub-project: (Mem/NB/HY)
12 * @e \$Revision: 56279 $ @e \$Date: 2011-07-11 13:11:28 -0600 (Mon, 11 Jul 2011) $
15 /*****************************************************************************
17 * Copyright (C) 2012 Advanced Micro Devices, Inc.
18 * All rights reserved.
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions are met:
22 * * Redistributions of source code must retain the above copyright
23 * notice, this list of conditions and the following disclaimer.
24 * * Redistributions in binary form must reproduce the above copyright
25 * notice, this list of conditions and the following disclaimer in the
26 * documentation and/or other materials provided with the distribution.
27 * * Neither the name of Advanced Micro Devices, Inc. nor the names of
28 * its contributors may be used to endorse or promote products derived
29 * from this software without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
32 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34 * DISCLAIMED. IN NO EVENT SHALL ADVANCED MICRO DEVICES, INC. BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 * ***************************************************************************
48 *----------------------------------------------------------------------------
51 *----------------------------------------------------------------------------
63 #include "OptionMemory.h" // need def for MEM_FEAT_BLOCK_NB
66 #include "cpuFamRegisters.h"
71 #define FILECODE PROC_MEM_NB_HY_MNDCTHY_FILECODE
73 /*----------------------------------------------------------------------------
74 * DEFINITIONS AND MACROS
76 *----------------------------------------------------------------------------
79 /*----------------------------------------------------------------------------
80 * TYPEDEFS AND STRUCTURES
82 *----------------------------------------------------------------------------
85 /*----------------------------------------------------------------------------
86 * PROTOTYPES OF LOCAL FUNCTIONS
88 *----------------------------------------------------------------------------
91 /*----------------------------------------------------------------------------
94 *----------------------------------------------------------------------------
97 extern BUILD_OPT_CFG UserOptions;
99 /* -----------------------------------------------------------------------------*/
103 * This function programs the memory controller with configuration parameters
106 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
108 * @return TRUE - An Error value lower than AGESA_FATAL may have occurred
109 * @return FALSE - An Error value greater than or equal to AGESA_FATAL may have occurred
110 * @return NBPtr->MCTPtr->ErrCode - Contains detailed AGESA_STATUS value
115 IN OUT MEM_NB_BLOCK *NBPtr
122 MEM_PARAMETER_STRUCT *RefPtr;
124 RefPtr = NBPtr->RefPtr;
125 MCTPtr = NBPtr->MCTPtr;
126 DCTPtr = NBPtr->DCTPtr;
127 //======================================================================
128 // Build Dram Control Register Value (F2x78)
129 //======================================================================
131 //It is recommended that these bits remain in the default state.
132 //MemNSetBitFieldNb (NBPtr, BFRdPtrInit, 5);
134 MemNSetBitFieldNb (NBPtr, BFEarlyArbEn, 1);
136 //======================================================================
137 // Build Dram Config Lo Register Value
138 //======================================================================
141 if (MCTPtr->Status[SbParDimms]) {
143 // SbParDimms should be set for all DDR3 RDIMMS
144 // Cannot turn off ParEn for DDR3
146 //@attention - add debug option for parity control
147 MemNSetBitFieldNb (NBPtr, BFParEn, 1);
151 if (MCTPtr->GangedMode) {
152 MemNSetBitFieldNb (NBPtr, BFWidth128, 1);
155 MemNSetBitFieldNb (NBPtr, BFX4Dimm, DCTPtr->Timings.Dimmx4Present & 0xF);
157 if (!MCTPtr->Status[SbRegistered]) {
158 MemNSetBitFieldNb (NBPtr, BFUnBuffDimm, 1);
161 if (MCTPtr->Status[SbEccDimms]) {
162 MemNSetBitFieldNb (NBPtr, BFDimmEccEn, 1);
165 //======================================================================
166 // Build Dram Config Hi Register Value
167 //======================================================================
170 MemNSetBitFieldNb (NBPtr, BFMemClkFreq, MemNGetMemClkFreqIdNb (NBPtr, DCTPtr->Timings.Speed));
172 if (MCTPtr->Status[SbRegistered]) {
173 if ((DCTPtr->Timings.Dimmx4Present != 0) && (DCTPtr->Timings.Dimmx8Present != 0)) {
174 MemNSetBitFieldNb (NBPtr, BFRDqsEn, 1);
178 if (RefPtr->EnableBankSwizzle) {
179 MemNSetBitFieldNb (NBPtr, BFBankSwizzleMode, 1);
182 if (DCTPtr->Timings.DimmQrPresent) {
183 if (UserOptions.CfgMemoryQuadrankType == QUADRANK_UNBUFFERED) {
184 MemNSetBitFieldNb (NBPtr, BFFourRankSoDimm, 1);
185 } else if (UserOptions.CfgMemoryQuadrankType == QUADRANK_REGISTERED) {
186 MemNSetBitFieldNb (NBPtr, BFFourRankRDimm, 1);
190 MemNSetBitFieldNb (NBPtr, BFDcqBypassMax, 0xF);
191 MemNSetBitFieldNb (NBPtr, BFDcqArbBypassEn, 1);
192 //======================================================================
193 // Build Dram Config Misc Register Value
194 //======================================================================
196 if (MCTPtr->Status[SbRegistered]) {
197 if (MemNGetBitFieldNb (NBPtr, BFDdr3Mode)!= 0) {
198 MemNSetBitFieldNb (NBPtr, BFSubMemclkRegDly, 1);
201 //======================================================================
202 // Build Dram Config Misc 2 Register Value
203 //======================================================================
206 // Ddr3FourSocketCh - Must be the same for both DCTs if either of them have > 2 Dimms
208 if ((GetMaxDimmsPerChannel (RefPtr->PlatformMemoryConfiguration, MCTPtr->SocketId, NBPtr->ChannelPtr->ChannelID)) > 2) {
209 MemNBrdcstSetNb (NBPtr, BFDdr3FourSocketCh, 1);
214 Value32 = MemNGetBitFieldNb (NBPtr, BFRdPtrInit);
215 if ((Value32 >= 2) && (Value32 <= 5)) {
216 MemNSetBitFieldNb (NBPtr, BFDataTxFifoWrDly, (6 - Value32));
222 if (MemNGetBitFieldNb (NBPtr, BFDdr3Mode) == 1) {
223 MemNSetBitFieldNb (NBPtr, BFProgOdtEn, 1);
225 MemNSetBitFieldNb (NBPtr, BFProgOdtEn, 0);
230 if ((MemNGetBitFieldNb (NBPtr, BFDdr3Mode) == 0) && (MemNGetBitFieldNb (NBPtr, BFFourRankRDimm) == 0) && (RefPtr->EnablePowerDown)) {
231 PowerDownMode = (UINT8) ((UserOptions.CfgPowerDownMode == POWER_DOWN_MODE_AUTO) ? POWER_DOWN_BY_CHANNEL : UserOptions.CfgPowerDownMode);
232 IDS_OPTION_HOOK (IDS_POWERDOWN_MODE, &PowerDownMode, &(NBPtr->MemPtr->StdHeader));
233 if (PowerDownMode == 1) {
234 MemNSetBitFieldNb (NBPtr, BFOdtSwizzle, 1);
239 return (BOOLEAN) (MCTPtr->ErrCode < AGESA_FATAL);
242 /* -----------------------------------------------------------------------------*/
246 * This function sends an MRS command
248 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
254 IN OUT MEM_NB_BLOCK *NBPtr
257 MemNSwapBitsNb (NBPtr);
259 IDS_HDT_CONSOLE (MEM_FLOW, "\t\t\tCS%d MR%d %04x\n",
260 (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 20) & 0xF,
261 (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) >> 16) & 0xF,
262 (MemNGetBitFieldNb (NBPtr, BFDramInitRegReg) & 0xFFFF));
264 // 1.Set SendMrsCmd=1
265 MemNSetBitFieldNb (NBPtr, BFSendMrsCmd, 1);
267 // 2.Wait for SendMrsCmd=0
268 MemNPollBitFieldNb (NBPtr, BFSendMrsCmd, 0, PCI_ACCESS_TIMEOUT, FALSE);
271 /* -----------------------------------------------------------------------------*/
275 * This function sends an MRS command to all CS of all channels
277 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
278 * @param[in,out] *DummyPtr - Unused pointer
284 MemNSendMrsCmdPerCsHy (
285 IN OUT MEM_NB_BLOCK *NBPtr,
286 IN OUT VOID *DummyPtr
293 if (!NBPtr->MCTPtr->Status[SbRegistered]) {
294 for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
295 NBPtr->SwitchDCT (NBPtr, Dct);
296 if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
297 IDS_HDT_CONSOLE (MEM_STATUS, "\tDct %d\n", Dct);
298 for (ChipSel = 0; ChipSel < MAX_CS_PER_CHANNEL; ChipSel++) {
299 if (NBPtr->GetSysAddr (NBPtr, ChipSel, &Dummy)) {
300 IDS_HDT_CONSOLE (MEM_STATUS, "\t\tCS %d\n", ChipSel);
301 // if chip select present
302 NBPtr->TechPtr->SendAllMRCmds (NBPtr->TechPtr, ChipSel);
303 // NOTE: wait 512 clocks for DLL-relock
304 MemUWait10ns (50000, NBPtr->MemPtr); // wait 500us
313 /* -----------------------------------------------------------------------------*/
317 * This is a general purpose function that executes before DRAM init
319 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
324 MemNBeforeDramInitHy (
325 IN OUT MEM_NB_BLOCK *NBPtr
329 for (Dct = 0; Dct < NBPtr->DctCount; Dct ++) {
330 MemNSwitchDCTNb (NBPtr, Dct);
331 if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
332 //Set PllLockTime and DllLockTime to default.
333 MemNSetBitFieldNb (NBPtr, BFPhyPLLLockTime, 0x000007D0);
334 MemNSetBitFieldNb (NBPtr, BFPhyDLLLockTime, 0x00000190);
335 MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 1);
340 /* -----------------------------------------------------------------------------*/
344 * Enable DLL Shut down
346 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
350 MemNEnDLLShutDownHy (
351 IN OUT MEM_NB_BLOCK *NBPtr
355 BOOLEAN DllShutDownEn;
357 DllShutDownEn = TRUE;
358 IDS_OPTION_HOOK (IDS_DLL_SHUT_DOWN, &DllShutDownEn, &(NBPtr->MemPtr->StdHeader));
360 if (DllShutDownEn && NBPtr->IsSupported[SetDllShutDown]) {
361 if ((NBPtr->ChannelPtr->MCTPtr->LogicalCpuid.Revision & AMD_F10_D1) != 0) {
362 for (Dct = 0; Dct < NBPtr->DctCount; Dct++) {
363 MemNSwitchDCTNb (NBPtr, Dct);
364 if (NBPtr->DCTPtr->Timings.DctMemSize != 0) {
365 MemNSetBitFieldNb (NBPtr, BFPhyPLLLockTime, 0x0000001C);
366 MemNSetBitFieldNb (NBPtr, BFPhyDLLLockTime, 0x0000013D);
367 MemNSetBitFieldNb (NBPtr, BFDisDllShutdownSR, 0);
374 /* -----------------------------------------------------------------------------*/
378 * Workaround for erratum 322 and 263
380 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
384 MemNBeforePlatformSpecHy (
385 IN OUT MEM_NB_BLOCK *NBPtr
389 if ((NBPtr->DCTPtr->Timings.Speed == DDR533_FREQUENCY) || (NBPtr->DCTPtr->Timings.Speed == DDR667_FREQUENCY)) {
390 MemNSetBitFieldNb (NBPtr, BFErr263, 0x0800);
392 MemNSetBitFieldNb (NBPtr, BFErr263, 0);
396 // 1.Write 00000000h to F2x[1,0]9C_xD08E000
397 MemNSetBitFieldNb (NBPtr, BFErr322I, 0);
398 // 2.If DRAM Configuration Register[MemClkFreq] (F2x[1,0]94[2:0]) is
399 // greater than or equal to 011b (DDR-800 and higher),
400 // then write 00000080h to F2x[1,0]9C_xD02E001,
401 // else write 00000090h to F2x[1,0]9C_xD02E001.
402 MemNSetBitFieldNb (NBPtr, BFErr322II, (NBPtr->DCTPtr->Timings.Speed >= DDR800_FREQUENCY) ? 0x80 : 0x90);
406 /* -----------------------------------------------------------------------------*/
409 * Initializes extended MMIO address space
411 * @param[in,out] *NBPtr - Pointer to the MEM_NB_BLOCK
412 * @param[in,out] OptParam - Optional parameter
417 MemNInitExtMMIOAddrHy (
418 IN OUT MEM_NB_BLOCK *NBPtr,
419 IN OUT VOID *OptParam
426 if (NBPtr->RefPtr->SysLimit >= _1TB_RJ16) {
427 // Initialize all indices of F1x114_x2 and F1x114_x3.
428 for (Index = 0; Index < 32; Index++) {
429 PciAddr = NBPtr->PciAddr;
430 PciAddr.Address.Function = 1;
432 PciAddr.Address.Register = 0x110;
433 Value = 0x20000000 | Index;
434 LibAmdPciWrite (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
436 PciAddr.Address.Register = 0x114;
438 LibAmdPciWrite (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
440 PciAddr.Address.Register = 0x110;
441 Value = 0x30000000 | Index;
442 LibAmdPciWrite (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
444 PciAddr.Address.Register = 0x114;
446 LibAmdPciWrite (AccessWidth32, PciAddr, &Value, &NBPtr->MemPtr->StdHeader);
452 /*----------------------------------------------------------------------------
455 *----------------------------------------------------------------------------