2 * This file is part of the LinuxBIOS project.
4 * Copyright (C) 2006 Indrek Kruusa <indrek.kruusa@artecdesign.ee>
5 * Copyright (C) 2006 Ronald G. Minnich <rminnich@gmail.com>
6 * Copyright (C) 2007 Advanced Micro Devices, Inc.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 #include <console/console.h>
26 #include <device/device.h>
27 #include <device/pci.h>
28 #include <device/pci_ids.h>
32 #include <cpu/amd/lxdef.h>
33 #include <cpu/x86/msr.h>
34 #include <cpu/x86/cache.h>
42 msr.whatever |= ID_CONFIG_SERIAL_SET;
50 msr = rdmsr(MC_GLD_MSR_PM);
56 /**************************************************************************
60 * Bugtool #465 and #609
62 * There is also fix code in cache and PCI functions. This bug is very is pervasive.
68 **************************************************************************/
75 * forces serialization of all load misses. Setting this bit prevents the
76 * DM pipe from backing up if a read request has to be held up waiting
77 * for PCI writes to complete.
79 msr = rdmsr(CPU_DM_CONFIG0);
80 msr.hi &= ~(7<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
81 msr.hi |= (2<<DM_CONFIG0_UPPER_WSREQ_SHIFT);
82 msr.lo |= DM_CONFIG0_LOWER_MISSER_SET;
83 wrmsr(CPU_DM_CONFIG0, msr);
85 /* interlock instruction fetches to WS regions with data accesses.
86 * This prevents an instruction fetch from going out to PCI if the
87 * data side is about to make a request.
89 msr = rdmsr(CPU_IM_CONFIG);
90 msr.lo |= IM_CONFIG_LOWER_QWT_SET;
91 wrmsr(CPU_IM_CONFIG, msr);
93 /* write serialize memory hole to PCI. Need to unWS when something is
94 * shadowed regardless of cachablility.
98 wrmsr( CPU_RCONF_A0_BF, msr);
99 wrmsr( CPU_RCONF_C0_DF, msr);
100 wrmsr( CPU_RCONF_E0_FF, msr);
103 /****************************************************************************
107 * Bugtool #784 + #792
109 * Fix CPUID instructions for < 3.0 CPUs
115 ****************************************************************************/
120 //static char *name = "Geode by NSC";
122 /* we'll do this the stupid way, for now, but that's the string they want. NO ONE KNOWS why you
123 * would do this -- the OS can figure this type of stuff out!
137 /* More CPUID to match AMD better. #792*/
139 msr.hi = 0x0C0C0A13D;
144 /* cpubug 1398: enable MC if we KNOW we have DDR*/
145 /**************************************************************************
149 * ClearQuest #IAENG1398
150 * The MC can not be enabled with SDR memory but can for DDR. Enable for
151 * DDR here if the setup token is "Default"
152 * Add this back to core by default once 2.0 CPUs are not supported.
157 **************************************************************************/
162 msr = rdmsr(MSR_GLCP+0x17);
163 if ((msr.lo & 0xff) <= CPU_REV_2_0) {
164 msr = rdmsr(GLCP_SYS_RSTPLL);
165 if (msr.lo & (1<<RSTPPL_LOWER_SDRMODE_SHIFT))
169 /* no CMOS/NVRAM to check, so enable MC Clock Gating */
170 msr = rdmsr(MC_GLD_MSR_PM);
171 msr.lo |= 3; /* enable MC clock gating.*/
172 wrmsr(MC_GLD_MSR_PM, msr);
175 /***************************************************************************
179 * Clear Quest IAENG00002900, VSS 118.150
181 * BTB issue causes blue screen in windows, but the fix is required
182 * for all operating systems.
188 **************************************************************************/
194 printk_debug("CPU_BUG:%s\n", __FUNCTION__);
195 /* Clear bit 43, disables the sysenter/sysexit in CPUID3 */
197 msr.hi &= 0xFFFFF7FF;
200 /* change this value to zero if you need to disable this BTB SWAPSiF. */
203 /* Disable enable_actions in DIAGCTL while setting up GLCP */
206 wrmsr(MSR_GLCP + 0x005f, msr);
208 /* Changing DBGCLKCTL register to GeodeLink */
211 wrmsr(MSR_GLCP + 0x0016, msr);
215 wrmsr(MSR_GLCP + 0x0016, msr);
217 /* The code below sets up the CPU to stall for 4 GeodeLink
218 * clocks when CPU is snooped. Because setting XSTATE to 0
219 * overrides any other XSTATE action, the code will always
220 * stall for 4 GeodeLink clocks after a snoop request goes
221 * away even if it occured a clock or two later than a
222 * different snoop; the stall signal will never 'glitch high'
223 * for only one or two CPU clocks with this code.
226 /* Send mb0 port 3 requests to upper GeodeLink diag bits
230 wrmsr(MSR_GLIU0 + 0x2005, msr);
232 /* set5m watches request ready from mb0 to CPU (snoop) */
235 wrmsr(MSR_GLCP + 0x0045, msr);
237 /* SET4M will be high when state is idle (XSTATE=11) */
240 wrmsr(MSR_GLCP + 0x0044, msr);
242 /* SET5n to watch for processor stalled state */
245 wrmsr(MSR_GLCP + 0x004D, msr);
247 /* Writing action number 13: XSTATE=0 to occur when CPU is
248 snooped unless we're stalled */
251 wrmsr(MSR_GLCP + 0x0075, msr);
253 /* Writing action number 11: inc XSTATE every GeodeLink clock
257 wrmsr(MSR_GLCP + 0x0073, msr);
259 /* Writing action number 5: STALL_CPU_PIPE when exitting idle
260 state or not in idle state */
263 wrmsr(MSR_GLCP + 0x006D, msr);
265 /* Writing DIAGCTL Register to enable the stall action and to
266 let set5m watch the upper GeodeLink diag bits. */
269 wrmsr(MSR_GLCP + 0x005f, msr);
275 /* GLPCI PIO Post Control shouldn't be enabled */
278 msr = rdmsr(GLPCI_SPARE);
279 msr.lo &= ~GLPCI_SPARE_LOWER_PPC_SET;
280 wrmsr(GLPCI_SPARE, msr);
285 /* per AMD, do this always */
289 /* Disable enable_actions in DIAGCTL while setting up GLCP */
290 wrmsr(MSR_GLCP + 0x005f, msr);
292 /* SET2M fires if VG pri is odd (3, not 2) and Ystate=0 */
293 msrnum = MSR_GLCP + 0x042;
294 /* msr.hi = 2d6b8000h */;
299 /* SET3M fires if MBUS changed and VG pri is odd */
300 msrnum = MSR_GLCP + 0x043;
305 /* Put VG request data on lower diag bus */
306 msrnum = MSR_GLIU0 + 0x2005;
311 /* Increment Y state if SET3M if true */
312 msrnum = MSR_GLCP + 0x074;
317 /* Set up MBUS action to PRI=3 read of MBIU */
318 msrnum = MSR_GLCP + 0x020;
323 /* Trigger MBUS action if VG=pri3 and Y=0, this blocks most PCI */
324 msrnum = MSR_GLCP + 0x071;
329 /* Writing DIAGCTL */
330 msrnum = MSR_GLCP + 0x005f;
335 /* Code to enable FS2 even when BTB and VGTEAR SWAPSiFs are enabled */
336 /* As per Todd Roberts in PBz1094 and PBz1095 */
337 /* Moved from CPUREG to CPUBUG per Tom Sylla */
338 msrnum = 0x04C000042; /* GLCP SETMCTL Register */;
340 msr.hi |= 8; /* Bit 35 = MCP_IN */
346 /****************************************************************************/
348 /** DisableMemoryReorder*/
351 /** The MC reordered transactions incorrectly and breaks coherency.*/
352 /** Disable reording and take a potential performance hit.*/
353 /** This is safe to do here and not in MC init since there is nothing*/
354 /** to maintain coherency with and the cache is not enabled yet.*/
361 /****************************************************************************/
362 void disablememoryreadorder(void)
365 msr = rdmsr(MC_CF8F_DATA);
367 msr.hi |= CF8F_UPPER_REORDER_DIS_SET;
368 wrmsr(MC_CF8F_DATA, msr);
374 #if 0 //GX3: any CPU bugs to fix here? :)
378 msr = rdmsr(GLCP_CHIP_REVID);
382 printk_err("%s: rev < 0x20! bailing!\n");
385 printk_debug("Doing cpubug fixes for rev 0x%x\n", rev);
391 /* cs 5530 bug; ignore
405 printk_err("unknown rev %x, bailing\n", rev);
410 disablememoryreadorder();
411 printk_debug("Done cpubug fixes \n");