2 * This file is part of the coreboot project.
4 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 static u16 mctGet_NVbits(u8 index)
29 #if CONFIG_CPU_SOCKET_TYPE == 0x10 /* Socket F */
31 #elif CONFIG_CPU_SOCKET_TYPE == 0x11 /* AM3 */
33 #elif CONFIG_CPU_SOCKET_TYPE == 0x13 /* ASB2 */
35 //#elif SYSTEM_TYPE == MOBILE
40 val = MAX_NODES_SUPPORTED;
43 val = MAX_DIMMS_SUPPORTED;
47 /* Maximum platform supported memclk */
48 //val = 200; /* 200MHz(DDR400) */
49 //val = 266; /* 266MHz(DDR533) */
50 //val = 333; /* 333MHz(DDR667) */
51 val = 400; /* 400MHz(DDR800) */
54 #if SYSTEM_TYPE == SERVER
55 val = 1; /* memory bus ECC capable */
57 val = 0; /* memory bus ECC not capable */
61 /* Quad Rank DIMM slot type */
63 //val = 1; /* R4 (registered DIMMs in AMD server configuration) */
64 //val = 2; /* S4 (Unbuffered SO-DIMMS) */
67 #if (CONFIG_GFXUMA == 0)
69 #elif (CONFIG_GFXUMA == 1)
74 #if (CONFIG_GFXUMA == 0)
76 #elif (CONFIG_GFXUMA == 1)
80 case NV_MCTUSRTMGMODE:
81 val = 0; /* Automatic (recommended) */
82 //val = 1; /* Limited */
83 //val = 2; /* Manual */
86 //val = 0; /* 200MHz */
87 //val = 1; /* 266MHz */
91 /* Bank (chip select) interleaving */
92 //val = 0; /* disabled */
93 val = 1; /* enabled (recommended) */
96 //val = 0; /* Disabled */
97 val = 1; /* Enabled (recommended) */
100 val = 0; /* Normal (only to slots that have enabled DIMMs) */
101 //val = 1; /* Enable all memclocks */
103 case NV_SPDCHK_RESTRT:
104 val = 0; /* Exit current node initialization if any DIMM has SPD checksum error */
105 //val = 1; /* Ignore faulty SPD checksum (DIMM will still be disabled), continue current node intialization */
108 //val = 0; /*Skip dqs training */
109 val = 1; /* Perform dqs training */
112 val = 0; /* Disabled (recommended) */
113 //val = 1; /* Enable */
116 #if (CONFIG_GFXUMA == 0)
117 val = 0; /* 64 byte mode */
118 #elif (CONFIG_GFXUMA == 1)
119 val = 1; /* 32 byte mode */
123 //val = 0; /* Disable */
124 val = 1; /* Enable */
127 val = 0; /* per channel control */
128 //val = 1; /* per chip select control */
130 case NV_CLKHZAltVidC3:
131 val = 0; /* disable */
132 //val = 1; /* enable */
135 #if (CONFIG_GFXUMA == 0)
136 val = 0xE0; /* address bits [31:24] */
137 #elif (CONFIG_GFXUMA == 1)
138 val = 0xC0; /* address bits [31:24] */
142 #if (CONFIG_GFXUMA == 0)
143 val = 0xE0; /* address bits [31:24] */
144 #elif (CONFIG_GFXUMA == 1)
145 val = 0xC0; /* address bits [31:24] */
149 #if (SYSTEM_TYPE == SERVER)
150 val = 1; /* Enable */
152 val = 0; /* Disable */
156 #if (SYSTEM_TYPE == SERVER)
157 val = 1; /* Enable */
159 val = 0; /* Disable */
163 #if (SYSTEM_TYPE == SERVER)
164 val = 1; /* Enable */
166 val = 0; /* Disable */
170 val = 0; /* Disable */
171 //val = 1; /* Enable */
174 val = 0x00; /* Disabled */
175 //val = 0x01; /* 40ns */
176 //val = 0x02; /* 80ns */
177 //val = 0x03; /* 160ns */
178 //val = 0x04; /* 320ns */
179 //val = 0x05; /* 640ns */
180 //val = 0x06; /* 1.28us */
181 //val = 0x07; /* 2.56us */
182 //val = 0x08; /* 5.12us */
183 //val = 0x09; /* 10.2us */
184 //val = 0x0a; /* 20.5us */
185 //val = 0x0b; /* 41us */
186 //val = 0x0c; /* 81.9us */
187 //val = 0x0d; /* 163.8us */
188 //val = 0x0e; /* 327.7us */
189 //val = 0x0f; /* 655.4us */
190 //val = 0x10; /* 1.31ms */
191 //val = 0x11; /* 2.62ms */
192 //val = 0x12; /* 5.24ms */
193 //val = 0x13; /* 10.49ms */
194 //val = 0x14; /* 20.97sms */
195 //val = 0x15; /* 42ms */
196 //val = 0x16; /* 84ms */
199 val = 0; /* Disabled - See L2Scrub in BKDG */
202 val = 0; /* Disabled - See DcacheScrub in BKDG */
205 val = 0; /* Disabled */
206 //val = 1; /* Enabled */
208 case NV_SyncOnUnEccEn:
209 val = 0; /* Disabled */
210 //val = 1; /* Enabled */
213 /* channel interleave is better performance than ganged mode at this time */
214 val = 1; /* Enabled */
215 //val = 0; /* Disabled */
217 case NV_ChannelIntlv:
218 val = 5; /* Not currently checked in mctchi_d.c */
219 /* Bit 0 = 0 - Disable
221 * Bits[2:1] = 00b - Address bits 6
222 * 01b - Address bits 1
223 * 10b - Hash*, XOR of address bits [20:16, 6]
224 * 11b - Hash*, XOR of address bits [20:16, 9]
233 static void mctHookAfterDIMMpre(void)
238 static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
240 pDCTstat->PresetmaxFreq = 400;
244 static void mctAdjustAutoCycTmg(void)
250 static void mctAdjustAutoCycTmg_D(void)
255 static void mctHookAfterAutoCycTmg(void)
260 static void mctGetCS_ExcludeMap(void)
265 static void mctHookAfterAutoCfg(void)
270 static void mctHookAfterPSCfg(void)
275 static void mctHookAfterHTMap(void)
280 static void mctHookAfterCPU(void)
285 static void mctSaveDQSSigTmg_D(void)
290 static void mctGetDQSSigTmg_D(void)
295 static void mctHookBeforeECC(void)
300 static void mctHookAfterECC(void)
305 static void mctInitMemGPIOs_A(void)
311 static void mctInitMemGPIOs_A_D(void)
316 static void mctNodeIDDebugPort_D(void)
322 static void mctWarmReset(void)
328 static void mctWarmReset_D(void)
333 static void mctHookBeforeDramInit(void)
338 static void mctHookAfterDramInit(void)
342 #if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
343 static void coreDelay(u32 microseconds)
350 This seems like a hack to me...
351 It would be nice to have a central delay function. */
353 cycles = (microseconds * 100) << 3; /* x8 (number of 1.25ns ticks) */
355 if (!(rdmsr(HWCR).lo & TSC_FREQ_SEL_MASK)) {
356 msr_t pstate_msr = rdmsr(CUR_PSTATE_MSR);
357 if (!(rdmsr(0xC0010064+pstate_msr.lo).lo & NB_DID_M_ON)) {
358 cycles = cycles <<1; // half freq, double cycles
360 } // else should we keep p0 freq at the time of setting TSC_FREQ_SEL_MASK somewhere and check it here ?
362 now = rdmsr(TSC_MSR);
363 // avoid overflow when called near 2^32 ticks ~ 5.3 s boundaries
364 if (0xffffffff - cycles >= now.lo ) {
366 end.lo = now.lo + cycles;
368 end.hi = now.hi +1; //
369 end.lo = cycles - (1+(0xffffffff - now.lo));
372 now = rdmsr(TSC_MSR);
373 } while ((now.hi < end.hi) || ((now.hi == end.hi) && (now.lo < end.lo)));
377 static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
385 // 1. dummy read for each installed DIMM */
386 for (u8Channel = 0; u8Channel < 2; u8Channel++) {
387 // This will be 0 for vaild DIMMS, eles 8
388 u8Receiver = mct_InitReceiver_D(pDCTstat, u8Channel);
390 for (; u8Receiver < 8; u8Receiver += 2) {
391 u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
393 if(!u8Valid) { /* Address not supported on current CS */
394 print_t("vErrata350: Address not supported on current CS\n");
397 print_t("vErrata350: dummy read \n");
402 print_t("vErrata350: step 2a\n");
404 /* 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. */
405 u32DctDev = pDCTstat->dev_dct;
406 Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00008000);
408 ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG.
409 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
411 if(!pDCTstat->GangedMode) {
412 print_t("vErrata350: step 2b\n");
413 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00008000);
415 ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG
416 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
419 print_t("vErrata350: step 3\n");
420 /* 3. Wait at least 300 nanoseconds. */
423 print_t("vErrata350: step 4\n");
424 /* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
425 Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00000000);
427 if(!pDCTstat->GangedMode) {
428 print_t("vErrata350: step 4b\n");
429 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00000000);
432 print_t("vErrata350: step 5\n");
433 /* 5. Wait at least 2 microseconds. */
438 static void vErratum372(struct DCTStatStruc *pDCTstat)
440 msr_t msr = rdmsr(NB_CFG_MSR);
442 int nbPstate1supported = ! (msr.hi && (1 << (NB_GfxNbPstateDis -32))) ;
444 // is this the right way to check for NB pstate 1 or DDR3-1333 ?
445 if (((pDCTstat->PresetmaxFreq==1333)||(nbPstate1supported))
446 &&(!pDCTstat->GangedMode)) {
447 /* DisableCf8ExtCfg */
448 msr.hi &= ~(3 << (51 - 32));
449 wrmsr(NB_CFG_MSR, msr);
453 static void vErratum414(struct DCTStatStruc *pDCTstat)
456 for(; dct < 2 ; dct++)
458 int dRAMConfigHi = Get_NB32(pDCTstat->dev_dct,0x94 + (0x100 * dct));
459 int powerDown = dRAMConfigHi && (1 << PowerDownEn ) ;
460 int ddr3 = dRAMConfigHi && (1 << Ddr3Mode ) ;
461 int dRAMMRS = Get_NB32(pDCTstat->dev_dct,0x84 + (0x100 * dct));
462 int pchgPDModeSel = dRAMMRS && (1 << PchgPDModeSel ) ;
463 if (powerDown && ddr3 && pchgPDModeSel )
465 Set_NB32(pDCTstat->dev_dct,0x84 + (0x100 * dct), dRAMMRS & ~(1 << PchgPDModeSel) );
472 static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
474 #if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
475 /* FIXME : as of 25.6.2010 errata 350 and 372 should apply to ((RB|BL|DA)-C[23])|(HY-D[01])|(PH-E0) but I don't find constants for all of them */
476 if (pDCTstatA->LogicalCPUID & AMD_DRBH_Cx) {
477 vErrata350(pMCTstat, pDCTstatA);
478 vErratum372(pDCTstatA);
479 vErratum414(pDCTstatA);
484 #if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
485 static u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u32 val)
487 if (pDCTstatA->LogicalCPUID & AMD_DR_Bx) {
488 if (pDCTstatA->Status & (1 << SB_Registered)) {
496 static void mctHookAfterAnyTraining(void)
500 static u32 mctGetLogicalCPUID_D(u8 node)
502 return mctGetLogicalCPUID(node);
505 #if (CONFIG_DIMM_SUPPORT & 0x000F)!=0x0005 /* not needed for AMD_FAM10_DDR3 */
506 static u8 mctSetNodeBoundary_D(void)