595273ea77e60bdab4304b698a12892391eb3a98
[coreboot.git] / src / northbridge / amd / amdmct / wrappers / mcti_d.c
1 /*
2  * This file is part of the coreboot project.
3  *
4  * Copyright (C) 2007-2008 Advanced Micro Devices, Inc.
5  *
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 */
21 #include <delay.h>
22 u16 mctGet_NVbits(u8 index)
23 {
24         u16 val = 0;
25
26         switch (index) {
27         case NV_PACK_TYPE:
28 #if SYSTEM_TYPE == SERVER
29                 val = 0;
30 #elif SYSTEM_TYPE == DESKTOP
31                 val = 1;
32 //#elif SYSTEM_TYPE == MOBILE
33 //              val = 2;
34 #endif
35                 break;
36         case NV_MAX_NODES:
37                 val = MAX_NODES_SUPPORTED;
38                 break;
39         case NV_MAX_DIMMS:
40                 //val = MAX_DIMMS_SUPPORTED;
41                 val = 8;
42                 break;
43         case NV_MAX_MEMCLK:
44                 /* Maximum platform supported memclk */
45                 //val =  200;   /* 200MHz(DDR400) */
46                 //val =  266;   /* 266MHz(DDR533) */
47                 //val =  333;   /* 333MHz(DDR667) */
48                 val =  400;     /* 400MHz(DDR800) */
49                 break;
50         case NV_ECC_CAP:
51 #if SYSTEM_TYPE == SERVER
52                 val = 1;        /* memory bus ECC capable */
53 #else
54                 val = 0;        /* memory bus ECC not capable */
55 #endif
56                 break;
57         case NV_4RANKType:
58                 /* Quad Rank DIMM slot type */
59                 val = 0;        /* normal */
60                 //val = 1;      /* R4 (registered DIMMs in AMD server configuration) */
61                 //val = 2;      /* S4 (Unbuffered SO-DIMMS) */
62                 break;
63         case NV_BYPMAX:
64 #if   (UMA_SUPPORT == 0)
65                 val = 4;
66 #elif  (UMA_SUPPORT == 1)
67                 val = 7;
68 #endif
69                 break;
70         case NV_RDWRQBYP:
71 #if  (UMA_SUPPORT == 0)
72                 val = 2;
73 #elif (UMA_SUPPORT == 1)
74                 val = 3;
75 #endif
76                 break;
77         case NV_MCTUSRTMGMODE:
78                 val = 0;        /* Automatic (recommended) */
79                 //val = 1;      /* Limited */
80                 //val = 2;      /* Manual */
81                 break;
82         case NV_MemCkVal:
83                 //val = 0;      /* 200MHz */
84                 //val = 1;      /* 266MHz */
85                 val = 2;        /* 333MHz */
86                 break;
87         case NV_BankIntlv:
88                 /* Bank (chip select) interleaving */
89                 //val = 0;      /* disabled */
90                 val = 1;        /* enabled (recommended) */
91                 break;
92         case NV_MemHole:
93                 //val = 0;      /* Disabled */
94                 val = 1;        /* Enabled (recommended) */
95                 break;
96         case NV_AllMemClks:
97                 val = 0;        /* Normal (only to slots that have enabled DIMMs) */
98                 //val = 1;      /* Enable all memclocks */
99                 break;
100         case NV_SPDCHK_RESTRT:
101                 val = 0;        /* Exit current node initialization if any DIMM has SPD checksum error */
102                 //val = 1;      /* Ignore faulty SPD checksum (DIMM will still be disabled), continue current node intialization */
103                 break;
104         case NV_DQSTrainCTL:
105                 //val = 0;      /*Skip dqs training */
106                 val = 1;        /* Perform dqs training */
107                 break;
108         case NV_NodeIntlv:
109                 val = 0;        /* Disabled (recommended) */
110                 //val = 1;      /* Enable */
111                 break;
112         case NV_BurstLen32:
113 #if (UMA_SUPPORT == 0)
114                 val = 0;        /* 64 byte mode */
115 #elif (UMA_SUPPORT == 1)
116                 val = 1;        /* 32 byte mode */
117 #endif
118                 break;
119         case NV_CKE_PDEN:
120                 //val = 0;      /* Disable */
121                 val = 1;        /* Enable */
122                 break;
123         case NV_CKE_CTL:
124                 val = 0;        /* per channel control */
125                 //val = 1;      /* per chip select control */
126                 break;
127         case NV_CLKHZAltVidC3:
128                 val = 0;        /* disable */
129                 //val = 1;      /* enable */
130                 break;
131         case NV_BottomIO:
132                 val = 0xE0;     /* address bits [31:24] */
133                 break;
134         case NV_BottomUMA:
135 #if (UMA_SUPPORT == 0)
136                 val = 0xE0;     /* address bits [31:24] */
137 #elif (UMA_SUPPORT == 1)
138                 val = 0xB0;     /* address bits [31:24] */
139 #endif
140                 break;
141         case NV_ECC:
142 #if (SYSTEM_TYPE == SERVER)
143                 val = 1;        /* Enable */
144 #else
145                 val = 0;        /* Disable */
146 #endif
147                 break;
148         case NV_NBECC:
149 #if (SYSTEM_TYPE == SERVER)
150                 val = 1;        /* Enable */
151 #else
152                 val = 0;        /* Disable */
153 #endif
154                 break;
155         case NV_ChipKill:
156 #if (SYSTEM_TYPE == SERVER)
157                 val = 1;        /* Enable */
158 #else
159                 val = 0;        /* Disable */
160 #endif
161                 break;
162         case NV_ECCRedir:
163                 val = 0;        /* Disable */
164                 //val = 1;      /* Enable */
165                 break;
166         case NV_DramBKScrub:
167                 val = 0x00;     /* Disabled */
168                 //val = 0x01;   /* 40ns */
169                 //val = 0x02;   /* 80ns */
170                 //val = 0x03;   /* 160ns */
171                 //val = 0x04;   /* 320ns */
172                 //val = 0x05;   /* 640ns */
173                 //val = 0x06;   /* 1.28us */
174                 //val = 0x07;   /* 2.56us */
175                 //val = 0x08;   /* 5.12us */
176                 //val = 0x09;   /* 10.2us */
177                 //val = 0x0a;   /* 20.5us */
178                 //val = 0x0b;   /* 41us */
179                 //val = 0x0c;   /* 81.9us */
180                 //val = 0x0d;   /* 163.8us */
181                 //val = 0x0e;   /* 327.7us */
182                 //val = 0x0f;   /* 655.4us */
183                 //val = 0x10;   /* 1.31ms */
184                 //val = 0x11;   /* 2.62ms */
185                 //val = 0x12;   /* 5.24ms */
186                 //val = 0x13;   /* 10.49ms */
187                 //val = 0x14;   /* 20.97sms */
188                 //val = 0x15;   /* 42ms */
189                 //val = 0x16;   /* 84ms */
190                 break;
191         case NV_L2BKScrub:
192                 val = 0;        /* Disabled - See L2Scrub in BKDG */
193                 break;
194         case NV_DCBKScrub:
195                 val = 0;        /* Disabled - See DcacheScrub in BKDG */
196                 break;
197         case NV_CS_SpareCTL:
198                 val = 0;        /* Disabled */
199                 //val = 1;      /* Enabled */
200                 break;
201         case NV_SyncOnUnEccEn:
202                 val = 0;        /* Disabled */
203                 //val = 1;      /* Enabled */
204                 break;
205         case NV_Unganged:
206                 /* channel interleave is better performance than ganged mode at this time */
207                 val = 1;                /* Enabled */
208                 //val = 0;      /* Disabled */
209                 break;
210         case NV_ChannelIntlv:
211                 val = 5;        /* Not currently checked in mctchi_d.c */
212         /* Bit 0 =     0 - Disable
213          *             1 - Enable
214          * Bits[2:1] = 00b - Address bits 6
215          *             01b - Address bits 1
216          *             10b - Hash*, XOR of address bits [20:16, 6]
217          *             11b - Hash*, XOR of address bits [20:16, 9]
218          */
219                 break;
220         }
221
222         return val;
223 }
224
225
226 void mctHookAfterDIMMpre(void)
227 {
228 }
229
230
231 void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
232 {
233         pDCTstat->PresetmaxFreq = 400;
234 }
235
236
237 void mctAdjustAutoCycTmg(void)
238 {
239 }
240
241 void mctAdjustAutoCycTmg_D(void)
242 {
243 }
244
245
246 void mctHookAfterAutoCycTmg(void)
247 {
248 }
249
250
251 void mctGetCS_ExcludeMap(void)
252 {
253 }
254
255
256 void mctHookAfterAutoCfg(void)
257 {
258 }
259
260
261 void mctHookAfterPSCfg(void)
262 {
263 }
264
265
266 void mctHookAfterHTMap(void)
267 {
268 }
269
270
271 void mctHookAfterCPU(void)
272 {
273 }
274
275
276 void mctSaveDQSSigTmg_D(void)
277 {
278 }
279
280
281 void mctGetDQSSigTmg_D(void)
282 {
283 }
284
285
286 void mctHookBeforeECC(void)
287 {
288 }
289
290
291 void mctHookAfterECC(void)
292 {
293 }
294
295
296 void mctInitMemGPIOs_A(void)
297 {
298 }
299
300
301 void mctInitMemGPIOs_A_D(void)
302 {
303 }
304
305
306 void mctNodeIDDebugPort_D(void)
307 {
308 }
309
310
311 void mctWarmReset(void)
312 {
313 }
314
315 void mctWarmReset_D(void)
316 {
317 }
318
319
320 void mctHookBeforeDramInit(void)
321 {
322 }
323
324
325 void mctHookAfterDramInit(void)
326 {
327 }
328
329 static void coreDelay (void);
330
331
332 /* Erratum 350 */
333 void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
334 {
335         u8 u8Channel;
336         u8 u8Receiver;
337         u32 u32Addr;
338         u8 u8Valid;
339         u32 u32DctDev;
340
341         // 1. dummy read for each installed DIMM */
342         for (u8Channel = 0; u8Channel < 2; u8Channel++) {
343                 // This will be 0 for vaild DIMMS, eles 8
344                 u8Receiver = mct_InitReceiver_D(pDCTstat, u8Channel);
345
346                 for (; u8Receiver < 8; u8Receiver += 2) {
347                         u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
348
349                         if(!u8Valid) {  /* Address not supported on current CS */
350                                 print_t("vErrara350: Address not supported on current CS\n");
351                                 continue;
352                         }
353                         print_t("vErrara350: dummy read \n");
354                         read32_fs(u32Addr);
355                 }
356         }
357
358         print_t("vErrara350: step 2a\n");
359
360         /* 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. */
361         u32DctDev = pDCTstat->dev_dct;
362         Set_NB32_index_wait(u32DctDev, 0x098, 0x0c, 0x00008000);
363         /*                                                ^--- value
364                                                 ^---F2x[1, 0]9C_x0C DRAM Phy Miscellaneous Register
365                                          ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
366
367         if(!pDCTstat->GangedMode) {
368                 print_t("vErrara350: step 2b\n");
369                 Set_NB32_index_wait(u32DctDev, 0x198, 0x0c, 0x00008000);
370                 /*                                                ^--- value
371                                                         ^---F2x[1, 0]9C_x0C DRAM Phy Miscellaneous Register
372                                                 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
373         }
374
375         print_t("vErrara350: step 3\n");
376         /* 3. Wait at least 300 nanoseconds. */
377         coreDelay();
378
379         print_t("vErrara350: step 4\n");
380         /* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
381         Set_NB32_index_wait(u32DctDev, 0x098, 0x0c, 0x00000000);
382
383         if(!pDCTstat->GangedMode) {
384                 print_t("vErrara350: step 4b\n");
385                 Set_NB32_index_wait(u32DctDev, 0x198, 0x0c, 0x00000000);
386         }
387
388         print_t("vErrara350: step 5\n");
389         /* 5. Wait at least 2 microseconds. */
390         coreDelay();
391
392 }
393
394
395 void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
396 {
397         if (pDCTstatA->LogicalCPUID & AMD_RB_C2) {
398                 vErrata350(pMCTstat, pDCTstatA);
399         }
400 }
401
402 void mctHookAfterAnyTraining(void)
403 {
404 }
405
406 u32 mctGetLogicalCPUID_D(u8 node)
407 {
408         return mctGetLogicalCPUID(node);
409 }
410
411 u8 mctSetNodeBoundary_D(void)
412 {
413         return 0;
414 }