diff -urN linux-2.4.33-wt2-geode/arch/i386/kernel/setup.c linux-2.4.33-wt2-geode-oostore/arch/i386/kernel/setup.c --- linux-2.4.33-wt2-geode/arch/i386/kernel/setup.c 2006-10-22 18:00:26 +0200 +++ linux-2.4.33-wt2-geode-oostore/arch/i386/kernel/setup.c 2006-10-28 17:35:00 +0200 @@ -74,6 +74,8 @@ * Provisions for empty E820 memory regions (reported by certain BIOSes). * Alex Achenbach , December 2002. * + * NSC Geode improvments + * Hiroshi Miura , June, 2002. */ /* @@ -1297,6 +1299,122 @@ } __setup("nohighio", highio_setup); +#ifdef CONFIG_MGEODE +static int cx86_fpufast __initdata = 1; +static int __init cx86_fpufast_setup(char *str) +{ + cx86_fpufast = 0; + return 1; +} +__setup("no_cx86_fpufast", cx86_fpufast_setup); + +static int cx86_memwb_override __initdata = 1; +static int __init cx86_memwb_setup(char *str) +{ + cx86_memwb_override = 0; + return 1; +} +__setup("no_cx86_memwb", cx86_memwb_setup); + +static void __init set_cx86_memwb(void) +{ + unsigned long cr0; + unsigned long flags; + + if (cx86_memwb_override) { + printk(KERN_INFO "Enable Memory-Write-back mode on Cyrix/NSC processor.\n"); + local_irq_save(flags); + /* CCR2 bit 2: unlock NW bit */ + setCx86(CX86_CCR2, getCx86(CX86_CCR2) & ~0x04); + /* set 'Not Write-through' */ + cr0 = 0x20000000; + __asm__("movl %%cr0,%%eax\n\t" + "orl %0,%%eax\n\t" + "movl %%eax,%%cr0\n" + : : "r" (cr0) + :"ax"); + /* CCR2 bit 2: lock NW bit and set WT1 */ + setCx86(CX86_CCR2, getCx86(CX86_CCR2) | 0x14 ); + local_irq_restore(flags); + } +} + +static int cx86_reorder_override __initdata = 1; +static int __init cx86_reorder_setup(char *str) +{ + cx86_reorder_override = 0; + return 1; +} +__setup("no_cx86_reorder", cx86_reorder_setup); + +static void __init set_cx86_reorder(void) +{ + unsigned char ccr3; + unsigned long flags; + +#ifdef CONFIG_X86_OOSTORE + if (cx86_reorder_override) { + printk(KERN_INFO "Enable Memory access reorder on Cyrix/NSC processor.\n"); + local_irq_save(flags); + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ + /* Load/Store Serialize to mem access disable (=reorder it) */ + setCx86(CX86_PCR0, getCx86(CX86_PCR0) & ~0x80); + /* set load/store serialize from 1GB to 4GB */ + ccr3 |= 0xe0; + setCx86(CX86_CCR3, ccr3); + local_irq_restore(flags); + } +#endif +} + +static int cx86_dtecache __initdata = 1; +static int __init cx86_dtecache_setup(char *str) +{ + cx86_dtecache = 0; + return 1; +} +__setup("no_cx86_dtecache", cx86_dtecache_setup); + +static int cx86_bypass __initdata = 1; +static int __init cx86_bypass_setup(char *str) +{ + cx86_bypass = 0; + return 1; +} +__setup("no_cx86_bypass", cx86_bypass_setup); + +static int cx86_inc __initdata = 1; +static int __init cx86_inc_setup(char *str) +{ + cx86_inc = 0; + return 1; +} +__setup("no_cx86_incrementor", cx86_inc_setup); + +static void set_cx86_inc(void) +{ + unsigned char ccr3; + unsigned long flags; + + if (cx86_inc) { + printk(KERN_INFO "Enable Incrementor on Cyrix/NSC processor.\n"); + local_irq_save(flags); + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ + /* PCR1 -- Performance Control */ + /* Incrementor on, whatever that is */ + setCx86(CX86_PCR1, getCx86(CX86_PCR1) | 0x02); + /* PCR0 -- Performance Control */ + /* Incrementor Margin 10 */ + setCx86(CX86_PCR0, getCx86(CX86_PCR0) | 0x04); + setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ + local_irq_restore(flags); + } +} + +#endif + static int __init get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; @@ -1731,22 +1849,37 @@ /* GXm supports extended cpuid levels 'ala' AMD */ if (c->cpuid_level == 2) { get_model_name(c); /* get CPU marketing name */ - /* - * The 5510/5520 companion chips have a funky PIT - * that breaks the TSC synchronizing, so turn it off - */ - if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) || - pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL)) - clear_bit(X86_FEATURE_TSC, c->x86_capability); +#ifdef CONFIG_MGEODE + if (((0x54 >= dir1) && (dir1 >= 0x50)) + || (dir1 >= 0x63)) { /* NSC Geode GXlv/GXm/GX1 */ + /* I dont know about Cyrix GXm/GXi */ + unsigned char ccr3, ccr4; + unsigned long flags; + + local_irq_save(flags); + ccr3 = getCx86(CX86_CCR3); + setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN */ + ccr4 = getCx86(CX86_CCR4); + if (cx86_fpufast) ccr4 |= 0x20; + if (cx86_dtecache) ccr4 |= 0x10; + if (cx86_bypass) ccr4 |= 0x08; + setCx86(CX86_CCR4, ccr4); + setCx86(CX86_CCR3, ccr3); /* disable MAPEN */ + local_irq_restore(flags); + + set_cx86_memwb(); + set_cx86_reorder(); + set_cx86_inc(); + } + /* Enable cxMMX extensions (GX1 Datasheet 54) */ + setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1); +#endif return; } else { /* MediaGX */ Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4'; p = Cx86_cb+2; c->x86_model = (dir1 & 0x20) ? 1 : 2; - if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) || - pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL)) - clear_bit(X86_FEATURE_TSC, &c->x86_capability); } break; diff -urN linux-2.4.33-wt2-geode/include/asm-i386/processor.h linux-2.4.33-wt2-geode-oostore/include/asm-i386/processor.h --- linux-2.4.33-wt2-geode/include/asm-i386/processor.h 2006-10-25 08:29:25 +0200 +++ linux-2.4.33-wt2-geode-oostore/include/asm-i386/processor.h 2006-10-28 17:36:10 +0200 @@ -222,10 +222,13 @@ #define CX86_CCR5 0xe9 #define CX86_CCR6 0xea #define CX86_CCR7 0xeb +#define CX86_PCR0 0x20 +#define CX86_PCR1 0xf0 #define CX86_DIR0 0xfe #define CX86_DIR1 0xff #define CX86_ARR_BASE 0xc4 #define CX86_RCR_BASE 0xdc +#define CX86_GCR 0xb8 /* * Cyrix CPU indexed register access macros