Commit 8780d138 authored by Dave Jones's avatar Dave Jones

[PATCH] Add support for National Semiconductor x86's.

These are mostly Cyrix-alike, but for some quirks we work around.
parent db8b4099
......@@ -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)
{
......@@ -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,13 +1409,8 @@ 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.
......@@ -1431,7 +1429,16 @@ 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 */
/*
* 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;
}
......@@ -1439,7 +1446,9 @@ static void __init init_cyrix(struct cpuinfo_x86 *c)
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;
......@@ -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)
......
......@@ -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); })
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment