632b581289c7bed1c80202eee9e065a16772f565
[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 static u16 mctGet_NVbits(u8 index)
23 {
24         u16 val = 0;
25
26         switch (index) {
27         case NV_PACK_TYPE:
28 #if CONFIG_CPU_SOCKET_TYPE == 0x10      /* Socket F */
29                 val = 0;
30 #elif CONFIG_CPU_SOCKET_TYPE == 0x11   /* AM2r2 */
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 static void mctHookAfterDIMMpre(void)
227 {
228 }
229
230
231 static void mctGet_MaxLoadFreq(struct DCTStatStruc *pDCTstat)
232 {
233         pDCTstat->PresetmaxFreq = 400;
234 }
235
236 #ifdef UNUSED_CODE
237 static void mctAdjustAutoCycTmg(void)
238 {
239 }
240 #endif
241
242
243 static void mctAdjustAutoCycTmg_D(void)
244 {
245 }
246
247
248 static void mctHookAfterAutoCycTmg(void)
249 {
250 }
251
252
253 static void mctGetCS_ExcludeMap(void)
254 {
255 }
256
257
258 static void mctHookAfterAutoCfg(void)
259 {
260 }
261
262
263 static void mctHookAfterPSCfg(void)
264 {
265 }
266
267
268 static void mctHookAfterHTMap(void)
269 {
270 }
271
272
273 static void mctHookAfterCPU(void)
274 {
275 }
276
277
278 static void mctSaveDQSSigTmg_D(void)
279 {
280 }
281
282
283 static void mctGetDQSSigTmg_D(void)
284 {
285 }
286
287
288 static void mctHookBeforeECC(void)
289 {
290 }
291
292
293 static void mctHookAfterECC(void)
294 {
295 }
296
297 #ifdef UNUSED_CODE
298 static void mctInitMemGPIOs_A(void)
299 {
300 }
301 #endif
302
303
304 static void mctInitMemGPIOs_A_D(void)
305 {
306 }
307
308
309 static void mctNodeIDDebugPort_D(void)
310 {
311 }
312
313
314 #ifdef UNUSED_CODE
315 static void mctWarmReset(void)
316 {
317 }
318 #endif
319
320
321 static void mctWarmReset_D(void)
322 {
323 }
324
325
326 static void mctHookBeforeDramInit(void)
327 {
328 }
329
330
331 static void mctHookAfterDramInit(void)
332 {
333 }
334
335 static void coreDelay (void);
336
337
338 /* Erratum 350 */
339 static void vErrata350(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstat)
340 {
341         u8 u8Channel;
342         u8 u8Receiver;
343         u32 u32Addr;
344         u8 u8Valid;
345         u32 u32DctDev;
346
347         // 1. dummy read for each installed DIMM */
348         for (u8Channel = 0; u8Channel < 2; u8Channel++) {
349                 // This will be 0 for vaild DIMMS, eles 8
350                 u8Receiver = mct_InitReceiver_D(pDCTstat, u8Channel);
351
352                 for (; u8Receiver < 8; u8Receiver += 2) {
353                         u32Addr = mct_GetRcvrSysAddr_D(pMCTstat, pDCTstat, u8Channel, u8Receiver, &u8Valid);
354
355                         if(!u8Valid) {  /* Address not supported on current CS */
356                                 print_t("vErrata350: Address not supported on current CS\n");
357                                 continue;
358                         }
359                         print_t("vErrata350: dummy read \n");
360                         read32_fs(u32Addr);
361                 }
362         }
363
364         print_t("vErrata350: step 2a\n");
365
366         /* 2. Write 0000_8000h to register F2x[1, 0]9C_xD080F0C. */
367         u32DctDev = pDCTstat->dev_dct;
368         Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00008000);
369         /*                                                ^--- value
370                                                 ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG.
371                                          ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
372
373         if(!pDCTstat->GangedMode) {
374                 print_t("vErrata350: step 2b\n");
375                 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00008000);
376                 /*                                                ^--- value
377                                                         ^---F2x[1, 0]9C_x0D080F0C, No description in BKDG
378                                                 ^----F2x[1, 0]98 DRAM Controller Additional Data Offset Register */
379         }
380
381         print_t("vErrata350: step 3\n");
382         /* 3. Wait at least 300 nanoseconds. */
383         coreDelay();
384
385         print_t("vErrata350: step 4\n");
386         /* 4. Write 0000_0000h to register F2x[1, 0]9C_xD080F0C. */
387         Set_NB32_index_wait(u32DctDev, 0x098, 0xD080F0C, 0x00000000);
388
389         if(!pDCTstat->GangedMode) {
390                 print_t("vErrata350: step 4b\n");
391                 Set_NB32_index_wait(u32DctDev, 0x198, 0xD080F0C, 0x00000000);
392         }
393
394         print_t("vErrata350: step 5\n");
395         /* 5. Wait at least 2 microseconds. */
396         coreDelay();
397
398 }
399
400
401 static void mctHookBeforeAnyTraining(struct MCTStatStruc *pMCTstat, struct DCTStatStruc *pDCTstatA)
402 {
403         if (pDCTstatA->LogicalCPUID & (AMD_RB_C2 | AMD_DA_C2)) {
404                 vErrata350(pMCTstat, pDCTstatA);
405         }
406 }
407
408 static void mctHookAfterAnyTraining(void)
409 {
410 }
411
412 static u32 mctGetLogicalCPUID_D(u8 node)
413 {
414         return mctGetLogicalCPUID(node);
415 }
416
417 static u8 mctSetNodeBoundary_D(void)
418 {
419         return 0;
420 }