This patch converts __FUNCTION__ to __func__, since __func__ is standard.
[coreboot.git] / src / cpu / amd / model_gx2 / cpubug.c
1 #include <console/console.h>
2 #include <arch/io.h>
3 #include <stdint.h>
4 #include <device/device.h>
5 #include <device/pci.h>
6 #include <device/pci_ids.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <bitops.h>
10 #include <cpu/amd/gx2def.h>
11 #include <cpu/x86/msr.h>
12 #include <cpu/x86/cache.h>
13
14
15 #if 0
16 void
17 bug645(void){
18         msr_t msr;
19         rdmsr(CPU_ID_CONFIG);
20         msr.whatever |= ID_CONFIG_SERIAL_SET;
21         wrmsr(msr);
22 }
23
24 void
25 bug573(void){
26         msr_t msr;
27
28         msr = rdmsr(MC_GLD_MSR_PM);
29         msr.eax &= 0xfff3;
30         wrmsr(MC_GLD_MSR_PM);
31 }
32 #endif
33
34 /**************************************************************************
35  *
36  *      pcideadlock
37  *
38  *      Bugtool #465 and #609
39  *      PCI cache deadlock
40  *      There is also fix code in cache and PCI functions. This bug is very is pervasive.
41  *
42  *      Entry:
43  *      Exit:
44  *      Modified:
45  *
46  **************************************************************************/
47 static void
48 pcideadlock(void)
49 {
50         msr_t msr;
51
52         /*
53          * forces serialization of all load misses. Setting this bit prevents the 
54          * DM pipe from backing up if a read request has to be held up waiting 
55          * for PCI writes to complete.
56         */
57         msr = rdmsr(CPU_DM_CONFIG0);
58         msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
59         msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
60         msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
61         wrmsr(CPU_DM_CONFIG0, msr);
62
63         /* interlock instruction fetches to WS regions with data accesses.
64          * This prevents an instruction fetch from going out to PCI if the 
65          * data side is about to make a request.
66          */
67         msr = rdmsr(CPU_IM_CONFIG);
68         msr.lo |= IM_CONFIG_LOWER_QWT_SET;
69         wrmsr(CPU_IM_CONFIG, msr);
70         
71         /* write serialize memory hole to PCI. Need to unWS when something is 
72          * shadowed regardless of cachablility.
73          */
74         msr.lo = 0x021212121;
75         msr.hi = 0x021212121;
76         wrmsr( CPU_RCONF_A0_BF, msr);
77         wrmsr( CPU_RCONF_C0_DF, msr);
78         wrmsr( CPU_RCONF_E0_FF, msr);
79 }
80
81 /**************************************************************************** 
82  *
83  *      CPUbug784
84  *
85  *      Bugtool #784 + #792
86  *
87  *      Fix CPUID instructions for < 3.0 CPUs
88  *
89  *      Entry:
90  *      Exit:
91  *      Modified:
92  *
93  ****************************************************************************/
94
95 void bug784(void)
96 {
97         msr_t msr;
98         //static char *name = "Geode by NSC";
99
100         /* we'll do this the stupid way, for now, but that's the string they want. NO ONE KNOWS why you
101          * would do this -- the OS can figure this type of stuff out!
102          */
103         msr = rdmsr(0x3006);
104         msr.hi = 0x646f6547;
105         wrmsr(0x3006, msr);
106
107         msr = rdmsr(0x3007);
108         msr.hi = 0x79622065;
109         msr.lo = 0x43534e20;
110         wrmsr(0x3007, msr);
111
112         msr = rdmsr(0x3002);
113         wrmsr(0x3008, msr);
114
115         /* More CPUID to match AMD better. #792*/
116         msr = rdmsr(0x3009);
117         msr.hi = 0x0C0C0A13D;
118         msr.lo = 0x00000000;
119         wrmsr(0x3009, msr);
120 }
121
122 /* cpubug 1398: enable MC if we KNOW we have DDR*/
123 /**************************************************************************
124  *
125  *      CPUbugIAENG1398
126  *
127  *      ClearQuest #IAENG1398
128  *      The MC can not be enabled with SDR memory but can for DDR. Enable for
129  *      DDR here if the setup token is "Default"
130  *      Add this back to core by default once 2.0 CPUs are not supported.
131  *      Entry:
132  *      Exit:
133  *      Modified:
134  *
135  **************************************************************************/
136 void eng1398(void)
137 {
138         msr_t msr;
139
140         msr = rdmsr(MSR_GLCP+0x17);
141         if ((msr.lo & 0xff) <= CPU_REV_2_0) {
142                 msr = rdmsr(GLCP_SYS_RSTPLL);
143                 if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
144                         return;
145         }
146
147         /* no CMOS/NVRAM to check, so enable MC Clock Gating */
148         msr = rdmsr(MC_GLD_MSR_PM);
149         msr.lo |= 3; /* enable MC clock gating.*/
150         wrmsr(MC_GLD_MSR_PM, msr);
151 }
152
153 /***************************************************************************
154  *
155  *      CPUbugIAENG2900
156  *
157  *      Clear Quest IAENG00002900, VSS 118.150
158  *
159  *      BTB issue causes blue screen in windows, but the fix is required
160  *      for all operating systems.
161  *
162  *      Entry:
163  *      Exit:
164  *      Modified:
165  *
166  **************************************************************************/
167 void
168 eng2900(void)
169 {
170         msr_t msr;
171
172         printk_debug("CPU_BUG:%s\n", __func__);
173         /* Clear bit 43, disables the sysenter/sysexit in CPUID3 */
174         msr = rdmsr(0x3003);
175         msr.hi &= 0xFFFFF7FF;
176         wrmsr(0x3003, msr);
177
178         /* change this value to zero if you need to disable this BTB SWAPSiF. */
179         if (1) { 
180
181                 /* Disable enable_actions in DIAGCTL while setting up GLCP */
182                 msr.hi = 0;
183                 msr.lo = 0;
184                 wrmsr(MSR_GLCP + 0x005f, msr);
185
186                 /* Changing DBGCLKCTL register to GeodeLink */
187                 msr.hi = 0;
188                 msr.lo = 0;
189                 wrmsr(MSR_GLCP + 0x0016, msr);
190
191                 msr.hi = 0;
192                 msr.lo = 2;
193                 wrmsr(MSR_GLCP + 0x0016, msr);
194
195                 /* The code below sets up the CPU to stall for 4 GeodeLink 
196                  * clocks when CPU is snooped.  Because setting XSTATE to 0 
197                  * overrides any other XSTATE action, the code will always 
198                  * stall for 4 GeodeLink clocks after a snoop request goes 
199                  * away even if it occured a clock or two later than a 
200                  * different snoop; the stall signal will never 'glitch high' 
201                  * for only one or two CPU clocks with this code.
202                  */
203
204                 /* Send mb0 port 3 requests to upper GeodeLink diag bits 
205                    [63:32] */
206                 msr.hi = 0;
207                 msr.lo = 0x80338041;
208                 wrmsr(MSR_GLIU0 + 0x2005, msr);
209
210                 /* set5m watches request ready from mb0 to CPU (snoop) */
211                 msr.hi = 0x5ad68000;
212                 msr.lo = 0;
213                 wrmsr(MSR_GLCP + 0x0045, msr);
214
215                 /* SET4M will be high when state is idle (XSTATE=11) */
216                 msr.hi = 0;
217                 msr.lo = 0x0140;
218                 wrmsr(MSR_GLCP + 0x0044, msr);
219
220                 /* SET5n to watch for processor stalled state */
221                 msr.hi = 0x2000;
222                 msr.lo = 0;
223                 wrmsr(MSR_GLCP + 0x004D, msr);
224
225                 /* Writing action number 13: XSTATE=0 to occur when CPU is 
226                    snooped unless we're stalled */
227                 msr.hi = 0;
228                 msr.lo = 0x00400000;
229                 wrmsr(MSR_GLCP + 0x0075, msr);
230
231                 /* Writing action number 11: inc XSTATE every GeodeLink clock 
232                    unless we're idle */
233                 msr.hi = 0;
234                 msr.lo = 0x30000;
235                 wrmsr(MSR_GLCP + 0x0073, msr);
236
237                 /* Writing action number 5: STALL_CPU_PIPE when exitting idle 
238                    state or not in idle state */
239                 msr.hi = 0;
240                 msr.lo = 0x00430000;
241                 wrmsr(MSR_GLCP + 0x006D, msr);
242
243                 /* Writing DIAGCTL Register to enable the stall action and to 
244                    let set5m watch the upper GeodeLink diag bits. */
245                 msr.hi = 0;
246                 msr.lo = 0x80004000;
247                 wrmsr(MSR_GLCP + 0x005f, msr);
248         }
249 }
250
251 void bug118253(void)
252 {
253         /* GLPCI PIO Post Control shouldn't be enabled */
254         msr_t msr;
255
256         msr = rdmsr(GLPCI_SPARE);
257         msr.lo &= ~GLPCI_SPARE_LOWER_PPC_SET;
258         wrmsr(GLPCI_SPARE, msr);
259 }
260
261 void bug118339(void)
262 {
263         /* per AMD, do this always */
264         msr_t msr = {0,0};
265         int msrnum;
266
267         /* Disable enable_actions in DIAGCTL while setting up GLCP */
268         wrmsr(MSR_GLCP + 0x005f, msr);
269
270         /*  SET2M fires if VG pri is odd (3, not 2) and Ystate=0 */
271         msrnum =  MSR_GLCP + 0x042;
272         /*      msr.hi =  2d6b8000h */;
273         msr.hi =  0x596b8000;
274         msr.lo =  0x00000a00;
275         wrmsr(msrnum, msr);
276
277         /*  SET3M fires if MBUS changed and VG pri is odd */
278         msrnum =  MSR_GLCP + 0x043;
279         msr.hi =  0x596b8040;
280         msr.lo = 0;
281         wrmsr(msrnum, msr);
282
283         /*  Put VG request data on lower diag bus */
284         msrnum =  MSR_GLIU0 + 0x2005;
285         msr.hi = 0;
286         msr.lo =  0x80338041;
287         wrmsr(msrnum, msr);
288
289         /*  Increment Y state if SET3M if true */
290         msrnum =  MSR_GLCP + 0x074;
291         msr.hi = 0;
292         msr.lo =  0x0000c000;
293         wrmsr(msrnum, msr);
294
295         /*  Set up MBUS action to PRI=3 read of MBIU */
296         msrnum =  MSR_GLCP + 0x020;
297         msr.hi =  0x0000d863;
298         msr.lo =  0x20002000;
299         wrmsr(msrnum, msr);
300
301         /*  Trigger MBUS action if VG=pri3 and Y=0, this blocks most PCI */
302         msrnum =  MSR_GLCP + 0x071;
303         msr.hi = 0;
304         msr.lo =  0x00000c00;
305         wrmsr(msrnum, msr);
306
307         /* Writing DIAGCTL */
308         msrnum =  MSR_GLCP + 0x005f;
309         msr.hi = 0;
310         msr.lo =  0x80004000;
311         wrmsr(msrnum, msr);
312
313         /*  Code to enable FS2 even when BTB and VGTEAR SWAPSiFs are enabled */
314         /*  As per Todd Roberts in PBz1094 and PBz1095 */
315         /*  Moved from CPUREG to CPUBUG per Tom Sylla */
316         msrnum =  0x04C000042;          /*  GLCP SETMCTL Register */;
317         msr = rdmsr(msrnum);
318         msr.hi |= 8;                    /*  Bit 35 = MCP_IN */
319         wrmsr(msrnum, msr);
320 }
321
322
323
324 /****************************************************************************/
325 /***/
326 /**     DisableMemoryReorder*/
327 /***/
328 /**     PBZ 3659:*/
329 /**      The MC reordered transactions incorrectly and breaks coherency.*/
330 /**      Disable reording and take a potential performance hit.*/
331 /**      This is safe to do here and not in MC init since there is nothing*/
332 /**      to maintain coherency with and the cache is not enabled yet.*/
333 /***/
334 /***/
335 /**     Entry:*/
336 /**     Exit:*/
337 /**     Modified:*/
338 /***/
339 /****************************************************************************/
340 void disablememoryreadorder(void)
341 {       
342         msr_t msr;
343         msr = rdmsr(MC_CF8F_DATA);
344
345         msr.hi |=  CF8F_UPPER_REORDER_DIS_SET;
346         wrmsr(MC_CF8F_DATA, msr);
347 }
348
349 void
350 cpubug(void)
351 {
352         msr_t msr;
353         int rev;
354
355         msr = rdmsr(GLCP_CHIP_REVID);
356
357         rev = msr.lo & 0xff;
358         if (rev < 0x20) {
359                 printk_err("%s: rev < 0x20! bailing!\n");
360                 return;
361         }
362         printk_debug("Doing cpubug fixes for rev 0x%x\n", rev);
363         switch(rev)
364         {
365                 case 0x20:
366                         pcideadlock();
367                         eng1398();
368                         /* cs 5530 bug; ignore 
369                         bug752();
370                         */
371                         break;
372                 case 0x21:
373                         pcideadlock();
374                         eng1398();
375                         eng2900();
376                         bug118339();
377                         break;
378                 case 0x22:
379                 case 0x30: 
380                         break;
381                 default:
382                         printk_err("unknown rev %x, bailing\n", rev);
383                         return;
384         }
385         bug784();
386         bug118253();
387         disablememoryreadorder();
388         printk_debug("Done cpubug fixes \n");
389 }