]> git.hungrycats.org Git - linux/commitdiff
[PATCH] Add support for National Semiconductor x86's.
authorDave Jones <davej@suse.de>
Wed, 3 Apr 2002 04:01:22 +0000 (20:01 -0800)
committerDave Jones <davej@suse.de>
Wed, 3 Apr 2002 04:01:22 +0000 (20:01 -0800)
These are mostly Cyrix-alike, but for some quirks we work around.

arch/i386/kernel/setup.c
include/asm-i386/processor.h

index 201570c71a9e0f1389bfe37c49f91e3849366350..b4b1860f7ff8ab29892b0e712e1a08511fffd214 100644 (file)
@@ -99,6 +99,8 @@
 #endif
 #include <linux/highmem.h>
 #include <linux/bootmem.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
 #include <linux/seq_file.h>
 #include <linux/console.h>
 #include <asm/processor.h>
@@ -1244,7 +1246,7 @@ static int __init init_amd(struct cpuinfo_x86 *c)
 }
 
 /*
- * Read Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
+ * Read NSC/Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
  */
 static void __init do_cyrix_devid(unsigned char *dir0, unsigned char *dir1)
 {
@@ -1319,7 +1321,7 @@ extern void calibrate_delay(void) __init;
 static void __init check_cx686_slop(struct cpuinfo_x86 *c)
 {
        unsigned long flags;
-       
+
        if (Cx86_dir0_msb == 3) {
                unsigned char ccr3, ccr5;
 
@@ -1329,7 +1331,7 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
                ccr5 = getCx86(CX86_CCR5);
                if (ccr5 & 2)
                        setCx86(CX86_CCR5, ccr5 & 0xfd);  /* reset SLOP */
-               setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */
+               setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */
                local_irq_restore(flags);
 
                if (ccr5 & 2) { /* possible wrong calibration done */
@@ -1340,6 +1342,7 @@ static void __init check_cx686_slop(struct cpuinfo_x86 *c)
        }
 }
 
+
 static void __init init_cyrix(struct cpuinfo_x86 *c)
 {
        unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;
@@ -1406,17 +1409,12 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
                break;
 
        case 4: /* MediaGX/GXm */
-               /*
-                *      Life sometimes gets weiiiiiiiird if we use this
-                *      on the MediaGX. So we turn it off for now. 
-                */
-               
 #ifdef CONFIG_PCI
-               /* It isnt really a PCI quirk directly, but the cure is the
+               /* It isn't really a PCI quirk directly, but the cure is the
                   same. The MediaGX has deep magic SMM stuff that handles the
                   SB emulation. It thows away the fifo on disable_dma() which
                   is wrong and ruins the audio. 
-                   
+
                   Bug2: VSA1 has a wrap bug so that using maximum sized DMA 
                   causes bad things. According to NatSemi VSA2 has another
                   bug to do with 'hlt'. I've not seen any boards using VSA2
@@ -1431,15 +1429,26 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
 
                /* GXm supports extended cpuid levels 'ala' AMD */
                if (c->cpuid_level == 2) {
+                       /* Enable Natsemi MMX extensions */
+                       setCx86(CX86_CCR7, getCx86(CX86_CCR7) | 1);
+
                        get_model_name(c);  /* get CPU marketing name */
-                       clear_bit(X86_FEATURE_TSC, c->x86_capability);
+                       /*
+                        *  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);
                        return;
                }
                else {  /* MediaGX */
                        Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
                        p = Cx86_cb+2;
                        c->x86_model = (dir1 & 0x20) ? 1 : 2;
+#ifndef CONFIG_CS5520
                        clear_bit(X86_FEATURE_TSC, &c->x86_capability);
+#endif
                }
                break;
 
@@ -1457,7 +1466,7 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
                tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;
                Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];
                p = Cx86_cb+tmp;
-               if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))
+               if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))
                        (c->x86_model)++;
                /* Emulate MTRRs using Cyrix's ARRs. */
                set_bit(X86_FEATURE_CYRIX_ARR, &c->x86_capability);
@@ -2100,7 +2109,7 @@ static void __init init_intel(struct cpuinfo_x86 *c)
                }
                if ( l1i || l1d )
                        printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n",
-                              l1i, l1d);
+                             l1i, l1d);
                if ( l2 )
                        printk(KERN_INFO "CPU: L2 cache: %dK\n", l2);
                if ( l3 )
@@ -2207,6 +2216,8 @@ void __init get_cpu_vendor(struct cpuinfo_x86 *c)
                c->x86_vendor = X86_VENDOR_AMD;
        else if (!strcmp(v, "CyrixInstead"))
                c->x86_vendor = X86_VENDOR_CYRIX;
+       else if (!strcmp(v, "Geode by NSC"))
+               c->x86_vendor = X86_VENDOR_NSC;
        else if (!strcmp(v, "UMC UMC UMC "))
                c->x86_vendor = X86_VENDOR_UMC;
        else if (!strcmp(v, "CentaurHauls"))
@@ -2532,24 +2543,6 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
         * indicate the features this CPU genuinely supports!
         */
        switch ( c->x86_vendor ) {
-       case X86_VENDOR_UNKNOWN:
-       default:
-               /* Not much we can do here... */
-               /* Check if at least it has cpuid */
-               if (c->cpuid_level == -1)
-               {
-                       /* No cpuid. It must be an ancient CPU */
-                       if (c->x86 == 4)
-                               strcpy(c->x86_model_id, "486");
-                       else if (c->x86 == 3)
-                               strcpy(c->x86_model_id, "386");
-               }
-               break;
-
-       case X86_VENDOR_CYRIX:
-               init_cyrix(c);
-               break;
-
        case X86_VENDOR_AMD:
                init_amd(c);
                break;
@@ -2558,6 +2551,10 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
                init_centaur(c);
                break;
 
+       case X86_VENDOR_CYRIX:
+               init_cyrix(c);
+               break;
+
        case X86_VENDOR_INTEL:
                init_intel(c);
                break;
@@ -2566,13 +2563,32 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
                c->x86_cache_size = 256; /* A few had 1 MB... */
                break;
 
-       case X86_VENDOR_TRANSMETA:
-               init_transmeta(c);
+       case X86_VENDOR_NSC:
+        init_cyrix(c);
                break;
 
        case X86_VENDOR_RISE:
                init_rise(c);
                break;
+
+       case X86_VENDOR_TRANSMETA:
+               init_transmeta(c);
+               break;
+
+       case X86_VENDOR_UNKNOWN:
+       default:
+               /* Not much we can do here... */
+               /* Check if at least it has cpuid */
+               if (c->cpuid_level == -1)
+               {
+                       /* No cpuid. It must be an ancient CPU */
+                       if (c->x86 == 4)
+                               strcpy(c->x86_model_id, "486");
+                       else if (c->x86 == 3)
+                               strcpy(c->x86_model_id, "386");
+               }
+               break;
+
        }
 
        printk(KERN_DEBUG "CPU: After vendor init, caps: %08x %08x %08x %08x\n",
@@ -2650,14 +2666,15 @@ void __init dodgy_tsc(void)
 {
        get_cpu_vendor(&boot_cpu_data);
 
-       if ( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX )
+       if (( boot_cpu_data.x86_vendor == X86_VENDOR_CYRIX ) ||
+           ( boot_cpu_data.x86_vendor == X86_VENDOR_NSC   ))
                init_cyrix(&boot_cpu_data);
 }
 
 
 /* These need to match <asm/processor.h> */
 static char *cpu_vendor_names[] __initdata = {
-       "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
+       "Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta", "NSC" };
 
 
 void __init print_cpu_info(struct cpuinfo_x86 *c)
@@ -2698,10 +2715,10 @@ static int show_cpuinfo(struct seq_file *m, void *v)
         */
        static char *x86_cap_flags[] = {
                /* Intel-defined */
-               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
-               "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
-               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
-               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
+               "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
+               "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
+               "pat", "pse36", "pn", "clflush", NULL, "dts", "acpi", "mmx",
+               "fxsr", "sse", "sse2", "ss", "ht", "tm", "ia64", NULL,
 
                /* AMD-defined */
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
index 573dac8f51ab083dde425dd122a6e14cdb4a2760..13eec87ba8fdda0ad17a8c13f400111dd82b0f34 100644 (file)
@@ -59,6 +59,7 @@ struct cpuinfo_x86 {
 #define X86_VENDOR_CENTAUR 5
 #define X86_VENDOR_RISE 6
 #define X86_VENDOR_TRANSMETA 7
+#define X86_VENDOR_NSC 8
 #define X86_VENDOR_UNKNOWN 0xff
 
 /*
@@ -216,7 +217,7 @@ static inline void clear_in_cr4 (unsigned long mask)
 }
 
 /*
- *      Cyrix CPU configuration register indexes
+ *      NSC/Cyrix CPU configuration register indexes
  */
 #define CX86_CCR0 0xc0
 #define CX86_CCR1 0xc1
@@ -232,7 +233,7 @@ static inline void clear_in_cr4 (unsigned long mask)
 #define CX86_RCR_BASE 0xdc
 
 /*
- *      Cyrix CPU indexed register access macros
+ *      NSC/Cyrix CPU indexed register access macros
  */
 
 #define getCx86(reg) ({ outb((reg), 0x22); inb(0x23); })