blob: 2440d2e8edb974ff950865e9616b1f87f13acfe4 [file] [log] [blame]
Marc Jones8ae8c882007-12-19 01:32:08 +00001/*
Stefan Reinauer7e61e452008-01-18 10:35:56 +00002 * This file is part of the coreboot project.
Marc Jones8ae8c882007-12-19 01:32:08 +00003 *
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +00004 * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
Marc Jones8ae8c882007-12-19 01:32:08 +00005 *
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.
9 *
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.
14 *
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
18 */
19
20/* Call-backs */
Marco Schmidta7741922009-06-06 11:33:58 +000021#include <delay.h>
Stefan Reinauer6f57b512010-07-08 16:41:05 +000022
Myles Watson075fbe82010-04-15 05:19:29 +000023static u16 mctGet_NVbits(u8 index)
Marc Jones8ae8c882007-12-19 01:32:08 +000024{
25 u16 val = 0;
26
27 switch (index) {
28 case NV_PACK_TYPE:
Zheng Baodb8b4112009-07-01 07:01:32 +000029#if CONFIG_CPU_SOCKET_TYPE == 0x10 /* Socket F */
Marc Jones8ae8c882007-12-19 01:32:08 +000030 val = 0;
Zheng Baoeb75f652010-04-23 17:32:48 +000031#elif CONFIG_CPU_SOCKET_TYPE == 0x11 /* AM3 */
Marc Jones8ae8c882007-12-19 01:32:08 +000032 val = 1;
Zheng Baoeb75f652010-04-23 17:32:48 +000033#elif CONFIG_CPU_SOCKET_TYPE == 0x13 /* ASB2 */
34 val = 4;
Marc Jones8ae8c882007-12-19 01:32:08 +000035//#elif SYSTEM_TYPE == MOBILE
36// val = 2;
37#endif
38 break;
39 case NV_MAX_NODES:
40 val = MAX_NODES_SUPPORTED;
41 break;
42 case NV_MAX_DIMMS:
Kerry She99cfa1e2010-08-30 07:31:31 +000043 val = MAX_DIMMS_SUPPORTED;
44 //val = 8;
Marc Jones8ae8c882007-12-19 01:32:08 +000045 break;
46 case NV_MAX_MEMCLK:
47 /* Maximum platform supported memclk */
48 //val = 200; /* 200MHz(DDR400) */
49 //val = 266; /* 266MHz(DDR533) */
50 //val = 333; /* 333MHz(DDR667) */
Marc Jones471f1032011-06-03 19:59:52 +000051 val = MEM_MAX_LOAD_FREQ;; /* 400MHz(DDR800) */
Marc Jones8ae8c882007-12-19 01:32:08 +000052 break;
53 case NV_ECC_CAP:
54#if SYSTEM_TYPE == SERVER
55 val = 1; /* memory bus ECC capable */
56#else
57 val = 0; /* memory bus ECC not capable */
58#endif
59 break;
60 case NV_4RANKType:
61 /* Quad Rank DIMM slot type */
62 val = 0; /* normal */
63 //val = 1; /* R4 (registered DIMMs in AMD server configuration) */
64 //val = 2; /* S4 (Unbuffered SO-DIMMS) */
65 break;
66 case NV_BYPMAX:
Patrick Georgie1667822012-05-05 15:29:32 +020067#if !CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +000068 val = 4;
Patrick Georgif8f00622012-05-05 15:50:17 +020069#elif CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +000070 val = 7;
71#endif
72 break;
73 case NV_RDWRQBYP:
Patrick Georgie1667822012-05-05 15:29:32 +020074#if !CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +000075 val = 2;
Patrick Georgif8f00622012-05-05 15:50:17 +020076#elif CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +000077 val = 3;
78#endif
79 break;
80 case NV_MCTUSRTMGMODE:
81 val = 0; /* Automatic (recommended) */
82 //val = 1; /* Limited */
83 //val = 2; /* Manual */
84 break;
85 case NV_MemCkVal:
86 //val = 0; /* 200MHz */
87 //val = 1; /* 266MHz */
88 val = 2; /* 333MHz */
89 break;
90 case NV_BankIntlv:
91 /* Bank (chip select) interleaving */
92 //val = 0; /* disabled */
93 val = 1; /* enabled (recommended) */
94 break;
95 case NV_MemHole:
96 //val = 0; /* Disabled */
97 val = 1; /* Enabled (recommended) */
98 break;
99 case NV_AllMemClks:
100 val = 0; /* Normal (only to slots that have enabled DIMMs) */
101 //val = 1; /* Enable all memclocks */
102 break;
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 */
106 break;
107 case NV_DQSTrainCTL:
108 //val = 0; /*Skip dqs training */
109 val = 1; /* Perform dqs training */
110 break;
111 case NV_NodeIntlv:
112 val = 0; /* Disabled (recommended) */
113 //val = 1; /* Enable */
114 break;
115 case NV_BurstLen32:
Patrick Georgie1667822012-05-05 15:29:32 +0200116#if !CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +0000117 val = 0; /* 64 byte mode */
Patrick Georgif8f00622012-05-05 15:50:17 +0200118#elif CONFIG_GFXUMA
Marc Jones8ae8c882007-12-19 01:32:08 +0000119 val = 1; /* 32 byte mode */
120#endif
121 break;
122 case NV_CKE_PDEN:
123 //val = 0; /* Disable */
124 val = 1; /* Enable */
125 break;
126 case NV_CKE_CTL:
127 val = 0; /* per channel control */
128 //val = 1; /* per chip select control */
129 break;
130 case NV_CLKHZAltVidC3:
131 val = 0; /* disable */
132 //val = 1; /* enable */
133 break;
134 case NV_BottomIO:
Patrick Georgie1667822012-05-05 15:29:32 +0200135#if !CONFIG_GFXUMA
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +0000136 val = 0xE0; /* address bits [31:24] */
Patrick Georgif8f00622012-05-05 15:50:17 +0200137#elif CONFIG_GFXUMA
Scott Duplichanf3cce2f2010-11-13 19:07:59 +0000138 val = 0xC0; /* address bits [31:24] */
139#endif
Marc Jones8ae8c882007-12-19 01:32:08 +0000140 break;
141 case NV_BottomUMA:
Patrick Georgie1667822012-05-05 15:29:32 +0200142#if !CONFIG_GFXUMA
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +0000143 val = 0xE0; /* address bits [31:24] */
Patrick Georgif8f00622012-05-05 15:50:17 +0200144#elif CONFIG_GFXUMA
Scott Duplichanf3cce2f2010-11-13 19:07:59 +0000145 val = 0xC0; /* address bits [31:24] */
Marc Jones8ae8c882007-12-19 01:32:08 +0000146#endif
147 break;
148 case NV_ECC:
149#if (SYSTEM_TYPE == SERVER)
150 val = 1; /* Enable */
151#else
152 val = 0; /* Disable */
153#endif
154 break;
155 case NV_NBECC:
156#if (SYSTEM_TYPE == SERVER)
157 val = 1; /* Enable */
158#else
159 val = 0; /* Disable */
160#endif
161 break;
162 case NV_ChipKill:
163#if (SYSTEM_TYPE == SERVER)
164 val = 1; /* Enable */
165#else
166 val = 0; /* Disable */
167#endif
168 break;
169 case NV_ECCRedir:
170 val = 0; /* Disable */
171 //val = 1; /* Enable */
172 break;
173 case NV_DramBKScrub:
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 */
197 break;
198 case NV_L2BKScrub:
199 val = 0; /* Disabled - See L2Scrub in BKDG */
200 break;
201 case NV_DCBKScrub:
202 val = 0; /* Disabled - See DcacheScrub in BKDG */
203 break;
204 case NV_CS_SpareCTL:
205 val = 0; /* Disabled */
206 //val = 1; /* Enabled */
Stefan Reinauerce00f1d2008-12-05 22:38:18 +0000207 break;
Marc Jones8ae8c882007-12-19 01:32:08 +0000208 case NV_SyncOnUnEccEn:
209 val = 0; /* Disabled */
210 //val = 1; /* Enabled */
Stefan Reinauerce00f1d2008-12-05 22:38:18 +0000211 break;
Marc Jones8ae8c882007-12-19 01:32:08 +0000212 case NV_Unganged:
213 /* channel interleave is better performance than ganged mode at this time */
214 val = 1; /* Enabled */
215 //val = 0; /* Disabled */
Stefan Reinauerce00f1d2008-12-05 22:38:18 +0000216 break;
Marc Jones8ae8c882007-12-19 01:32:08 +0000217 case NV_ChannelIntlv:
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +0000218 val = 5; /* Not currently checked in mctchi_d.c */
Marc Jones8ae8c882007-12-19 01:32:08 +0000219 /* Bit 0 = 0 - Disable
220 * 1 - Enable
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]
225 */
Stefan Reinauerce00f1d2008-12-05 22:38:18 +0000226 break;
Marc Jones8ae8c882007-12-19 01:32:08 +0000227 }
228
229 return val;
230}
231
232
Myles Watson075fbe82010-04-15 05:19:29 +0000233static void mctHookAfterDIMMpre(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000234{
235}
236
237
Myles Watson075fbe82010-04-15 05:19:29 +0000238static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
Marc Jones8ae8c882007-12-19 01:32:08 +0000239{
Marc Jones471f1032011-06-03 19:59:52 +0000240 pDCTstat->PresetmaxFreq = MEM_MAX_LOAD_FREQ;
Marc Jones8ae8c882007-12-19 01:32:08 +0000241}
242
Stefan Reinauerd6532112010-04-16 00:31:44 +0000243#ifdef UNUSED_CODE
Myles Watson075fbe82010-04-15 05:19:29 +0000244static void mctAdjustAutoCycTmg(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000245{
246}
Stefan Reinauerd6532112010-04-16 00:31:44 +0000247#endif
248
Marc Jones8ae8c882007-12-19 01:32:08 +0000249
Myles Watson075fbe82010-04-15 05:19:29 +0000250static void mctAdjustAutoCycTmg_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000251{
252}
253
254
Myles Watson075fbe82010-04-15 05:19:29 +0000255static void mctHookAfterAutoCycTmg(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000256{
257}
258
259
Myles Watson075fbe82010-04-15 05:19:29 +0000260static void mctGetCS_ExcludeMap(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000261{
262}
263
264
Myles Watson075fbe82010-04-15 05:19:29 +0000265static void mctHookAfterAutoCfg(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000266{
267}
268
269
Myles Watson075fbe82010-04-15 05:19:29 +0000270static void mctHookAfterPSCfg(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000271{
272}
273
274
Myles Watson075fbe82010-04-15 05:19:29 +0000275static void mctHookAfterHTMap(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000276{
277}
278
279
Myles Watson075fbe82010-04-15 05:19:29 +0000280static void mctHookAfterCPU(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000281{
282}
283
284
Myles Watson075fbe82010-04-15 05:19:29 +0000285static void mctSaveDQSSigTmg_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000286{
287}
288
289
Myles Watson075fbe82010-04-15 05:19:29 +0000290static void mctGetDQSSigTmg_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000291{
292}
293
294
Myles Watson075fbe82010-04-15 05:19:29 +0000295static void mctHookBeforeECC(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000296{
297}
298
299
Myles Watson075fbe82010-04-15 05:19:29 +0000300static void mctHookAfterECC(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000301{
302}
303
Stefan Reinauerd6532112010-04-16 00:31:44 +0000304#ifdef UNUSED_CODE
Myles Watson075fbe82010-04-15 05:19:29 +0000305static void mctInitMemGPIOs_A(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000306{
307}
Stefan Reinauerd6532112010-04-16 00:31:44 +0000308#endif
Marc Jones8ae8c882007-12-19 01:32:08 +0000309
310
Myles Watson075fbe82010-04-15 05:19:29 +0000311static void mctInitMemGPIOs_A_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000312{
313}
314
315
Myles Watson075fbe82010-04-15 05:19:29 +0000316static void mctNodeIDDebugPort_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000317{
318}
319
320
Stefan Reinauerd6532112010-04-16 00:31:44 +0000321#ifdef UNUSED_CODE
Myles Watson075fbe82010-04-15 05:19:29 +0000322static void mctWarmReset(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000323{
324}
Stefan Reinauerd6532112010-04-16 00:31:44 +0000325#endif
326
Marc Jones8ae8c882007-12-19 01:32:08 +0000327
Myles Watson075fbe82010-04-15 05:19:29 +0000328static void mctWarmReset_D(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000329{
330}
331
332
Myles Watson075fbe82010-04-15 05:19:29 +0000333static void mctHookBeforeDramInit(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000334{
335}
336
337
Myles Watson075fbe82010-04-15 05:19:29 +0000338static void mctHookAfterDramInit(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000339{
340}
341
Stefan Reinauer817d7542010-07-08 00:37:23 +0000342#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
Xavi Drudis Ferranc3132102011-02-28 03:49:28 +0000343static void coreDelay(u32 microseconds)
344{
345 msr_t now;
346 msr_t end;
347 u32 cycles;
348
349 /* delay ~40us
350 This seems like a hack to me...
351 It would be nice to have a central delay function. */
352
353 cycles = (microseconds * 100) << 3; /* x8 (number of 1.25ns ticks) */
354
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
359 }
360 } // else should we keep p0 freq at the time of setting TSC_FREQ_SEL_MASK somewhere and check it here ?
361
362 now = rdmsr(TSC_MSR);
363 // avoid overflow when called near 2^32 ticks ~ 5.3 s boundaries
364 if (0xffffffff - cycles >= now.lo ) {
365 end.hi = now.hi;
366 end.lo = now.lo + cycles;
367 } else {
368 end.hi = now.hi +1; //
369 end.lo = cycles - (1+(0xffffffff - now.lo));
370 }
371 do {
372 now = rdmsr(TSC_MSR);
373 } while ((now.hi < end.hi) || ((now.hi == end.hi) && (now.lo < end.lo)));
374}
375
Marco Schmidta7741922009-06-06 11:33:58 +0000376/* Erratum 350 */
Myles Watson075fbe82010-04-15 05:19:29 +0000377static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
Marc Jones8ae8c882007-12-19 01:32:08 +0000378{
Marco Schmidta7741922009-06-06 11:33:58 +0000379 u8 u8Channel;
380 u8 u8Receiver;
381 u32 u32Addr;
382 u8 u8Valid;
383 u32 u32DctDev;
384
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);
389
390 for (; u8Receiver < 8; u8Receiver += 2) {
391 u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
392
393 if(!u8Valid) { /* Address not supported on current CS */
Zheng Bao69a031c2009-08-19 07:08:10 +0000394 print_t("vErrata350: Address not supported on current CS\n");
Marco Schmidta7741922009-06-06 11:33:58 +0000395 continue;
396 }
Zheng Bao69a031c2009-08-19 07:08:10 +0000397 print_t("vErrata350: dummy read \n");
Marco Schmidta7741922009-06-06 11:33:58 +0000398 read32_fs(u32Addr);
399 }
400 }
401
Zheng Bao69a031c2009-08-19 07:08:10 +0000402 print_t("vErrata350: step 2a\n");
Marco Schmidta7741922009-06-06 11:33:58 +0000403
404 /* 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. */
405 u32DctDev = pDCTstat->dev_dct;
Zheng Bao69a031c2009-08-19 07:08:10 +0000406 Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00008000);
Marco Schmidta7741922009-06-06 11:33:58 +0000407 /* ^--- value
Zheng Bao69a031c2009-08-19 07:08:10 +0000408 ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG.
Marco Schmidta7741922009-06-06 11:33:58 +0000409 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
410
411 if(!pDCTstat->GangedMode) {
Zheng Bao69a031c2009-08-19 07:08:10 +0000412 print_t("vErrata350: step 2b\n");
413 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00008000);
Marco Schmidta7741922009-06-06 11:33:58 +0000414 /* ^--- value
Zheng Bao69a031c2009-08-19 07:08:10 +0000415 ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG
Marco Schmidta7741922009-06-06 11:33:58 +0000416 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
417 }
418
Zheng Bao69a031c2009-08-19 07:08:10 +0000419 print_t("vErrata350: step 3\n");
Marco Schmidta7741922009-06-06 11:33:58 +0000420 /* 3. Wait at least 300 nanoseconds. */
Xavi Drudis Ferranc3132102011-02-28 03:49:28 +0000421 coreDelay(1);
Marco Schmidta7741922009-06-06 11:33:58 +0000422
Zheng Bao69a031c2009-08-19 07:08:10 +0000423 print_t("vErrata350: step 4\n");
Marco Schmidta7741922009-06-06 11:33:58 +0000424 /* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
Zheng Bao69a031c2009-08-19 07:08:10 +0000425 Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00000000);
Marco Schmidta7741922009-06-06 11:33:58 +0000426
427 if(!pDCTstat->GangedMode) {
Zheng Bao69a031c2009-08-19 07:08:10 +0000428 print_t("vErrata350: step 4b\n");
429 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00000000);
Marco Schmidta7741922009-06-06 11:33:58 +0000430 }
431
Zheng Bao69a031c2009-08-19 07:08:10 +0000432 print_t("vErrata350: step 5\n");
Marco Schmidta7741922009-06-06 11:33:58 +0000433 /* 5. Wait at least 2 microseconds. */
Xavi Drudis Ferranc3132102011-02-28 03:49:28 +0000434 coreDelay(2);
Marco Schmidta7741922009-06-06 11:33:58 +0000435
436}
Xavi Drudis Ferran213ab942010-08-22 19:51:34 +0000437
438static void vErratum372(struct DCTStatStruc *pDCTstat)
439{
440 msr_t msr = rdmsr(NB_CFG_MSR);
Xavi Drudis Ferran19245c92011-02-28 03:02:40 +0000441
Xavi Drudis Ferran213ab942010-08-22 19:51:34 +0000442 int nbPstate1supported = ! (msr.hi && (1 << (NB_GfxNbPstateDis -32))) ;
443
Xavi Drudis Ferran19245c92011-02-28 03:02:40 +0000444 // is this the right way to check for NB pstate 1 or DDR3-1333 ?
Xavi Drudis Ferran213ab942010-08-22 19:51:34 +0000445 if (((pDCTstat->PresetmaxFreq==1333)||(nbPstate1supported))
446 &&(!pDCTstat->GangedMode)) {
447 /* DisableCf8ExtCfg */
448 msr.hi &= ~(3 << (51 - 32));
449 wrmsr(NB_CFG_MSR, msr);
450 }
451}
Xavi Drudis Ferran4793ef12010-08-22 19:54:26 +0000452
453static void vErratum414(struct DCTStatStruc *pDCTstat)
454{
455 int dct=0;
Xavi Drudis Ferran19245c92011-02-28 03:02:40 +0000456 for(; dct < 2 ; dct++)
Xavi Drudis Ferran4793ef12010-08-22 19:54:26 +0000457 {
Xavi Drudis Ferran19245c92011-02-28 03:02:40 +0000458 int dRAMConfigHi = Get_NB32(pDCTstat->dev_dct,0x94 + (0x100 * dct));
Xavi Drudis Ferran4793ef12010-08-22 19:54:26 +0000459 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 ) ;
Xavi Drudis Ferran19245c92011-02-28 03:02:40 +0000463 if (powerDown && ddr3 && pchgPDModeSel )
Xavi Drudis Ferran4793ef12010-08-22 19:54:26 +0000464 {
465 Set_NB32(pDCTstat->dev_dct,0x84 + (0x100 * dct), dRAMMRS & ~(1 << PchgPDModeSel) );
466 }
467 }
468}
Stefan Reinauer817d7542010-07-08 00:37:23 +0000469#endif
Marco Schmidta7741922009-06-06 11:33:58 +0000470
471
Myles Watson075fbe82010-04-15 05:19:29 +0000472static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
Marco Schmidta7741922009-06-06 11:33:58 +0000473{
Zheng Baoeb75f652010-04-23 17:32:48 +0000474#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
Xavi Drudis Ferran213ab942010-08-22 19:51:34 +0000475 /* 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) {
Marco Schmidta7741922009-06-06 11:33:58 +0000477 vErrata350(pMCTstat, pDCTstatA);
Xavi Drudis Ferran213ab942010-08-22 19:51:34 +0000478 vErratum372(pDCTstatA);
Xavi Drudis Ferran4793ef12010-08-22 19:54:26 +0000479 vErratum414(pDCTstatA);
Marco Schmidta7741922009-06-06 11:33:58 +0000480 }
Zheng Baoeb75f652010-04-23 17:32:48 +0000481#endif
482}
483
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000484#if (CONFIG_DIMM_SUPPORT & 0x000F)==0x0005 /* AMD_FAM10_DDR3 */
Zheng Baoeb75f652010-04-23 17:32:48 +0000485static u32 mct_AdjustSPDTimings(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA, u32 val)
486{
487 if (pDCTstatA->LogicalCPUID & AMD_DR_Bx) {
488 if (pDCTstatA->Status & (1 << SB_Registered)) {
489 val ++;
490 }
491 }
492 return val;
Marc Jones8ae8c882007-12-19 01:32:08 +0000493}
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000494#endif
Marc Jones8ae8c882007-12-19 01:32:08 +0000495
Myles Watson075fbe82010-04-15 05:19:29 +0000496static void mctHookAfterAnyTraining(void)
Marc Jones8ae8c882007-12-19 01:32:08 +0000497{
498}
499
Myles Watson075fbe82010-04-15 05:19:29 +0000500static u32 mctGetLogicalCPUID_D(u8 node)
Marc Jones8ae8c882007-12-19 01:32:08 +0000501{
502 return mctGetLogicalCPUID(node);
503}
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +0000504
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000505#if (CONFIG_DIMM_SUPPORT & 0x000F)!=0x0005 /* not needed for AMD_FAM10_DDR3 */
Myles Watson075fbe82010-04-15 05:19:29 +0000506static u8 mctSetNodeBoundary_D(void)
Marc Jones (marc.jonese3aeb932008-04-11 03:20:28 +0000507{
508 return 0;
509}
Stefan Reinauer6f57b512010-07-08 16:41:05 +0000510#endif