Commit 00e3d89f authored by Dave Jones's avatar Dave Jones Committed by Dave Jones

[AGPGART] Add support for Intel 852GM / 855GM and 865G

parent 6669cc8a
...@@ -34,14 +34,17 @@ config AGP3 ...@@ -34,14 +34,17 @@ config AGP3
depends on AGP depends on AGP
config AGP_INTEL config AGP_INTEL
tristate "Intel 440LX/BX/GX and I815/I820/I830M/I830MP/I840/I845/I850/I860 support" tristate "Intel 440LX/BX/GX and I815/I820/830M/I830MP/I840/I845/845G/I850/852GM/855GM/I860/865G support"
depends on AGP depends on AGP
help help
This option gives you AGP support for the GLX component of the This option gives you AGP support for the GLX component of the
XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850 and 860 chipsets. XFree86 4.x on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850
and 860 chipsets and full support for the 810, 815, 830M, 845G,
852GM, 855GM and 865G integrated graphics chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N. use GLX or DRI, or if you have any Intel integrated graphics
chipsets. If unsure, say Y.
#config AGP_I810 #config AGP_I810
# tristate "Intel I810/I815/I830M (on-board) support" # tristate "Intel I810/I815/I830M (on-board) support"
......
...@@ -217,6 +217,34 @@ struct agp_bridge_data { ...@@ -217,6 +217,34 @@ struct agp_bridge_data {
/* This one is for I830MP w. an external graphic card */ /* This one is for I830MP w. an external graphic card */
#define INTEL_I830_ERRSTS 0x92 #define INTEL_I830_ERRSTS 0x92
/* Intel 855GM/852GM registers */
#define I855_GMCH_GMS_STOLEN_0M 0x0
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
#define I85X_CAPID 0x44
#define I85X_VARIANT_MASK 0x7
#define I85X_VARIANT_SHIFT 5
#define I855_GME 0x0
#define I855_GM 0x4
#define I852_GME 0x2
#define I852_GM 0x5
#ifndef PCI_DEVICE_ID_INTEL_82855_HB
#define PCI_DEVICE_ID_INTEL_82855_HB 0x3580
#endif
#ifndef PCI_DEVICE_ID_INTEL_82855_IG
#define PCI_DEVICE_ID_INTEL_82855_IG 0x3582
#endif
#ifndef PCI_DEVICE_ID_INTEL_82865_HB
#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570
#endif
#ifndef PCI_DEVICE_ID_INTEL_82865_IG
#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572
#endif
/* intel 815 register */ /* intel 815 register */
#define INTEL_815_APCONT 0x51 #define INTEL_815_APCONT 0x51
#define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF #define INTEL_815_ATTBASE_MASK ~0x1FFFFFFF
......
...@@ -2,6 +2,11 @@ ...@@ -2,6 +2,11 @@
* Intel AGPGART routines. * Intel AGPGART routines.
*/ */
/*
* Intel(R) 855GM/852GM and 865G support added by David Dawes
* <dawes@tungstengraphics.com>.
*/
#include <linux/module.h> #include <linux/module.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -294,34 +299,62 @@ static void intel_i830_init_gtt_entries(void) ...@@ -294,34 +299,62 @@ static void intel_i830_init_gtt_entries(void)
u16 gmch_ctrl; u16 gmch_ctrl;
int gtt_entries; int gtt_entries;
u8 rdct; u8 rdct;
int local = 0;
static const int ddt[4] = { 0, 16, 32, 64 }; static const int ddt[4] = { 0, 16, 32, 64 };
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl); pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) { switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I830_GMCH_GMS_STOLEN_512: case I830_GMCH_GMS_STOLEN_512:
gtt_entries = KB(512) - KB(132); gtt_entries = KB(512) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break; break;
case I830_GMCH_GMS_STOLEN_1024: case I830_GMCH_GMS_STOLEN_1024:
gtt_entries = MB(1) - KB(132); gtt_entries = MB(1) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break; break;
case I830_GMCH_GMS_STOLEN_8192: case I830_GMCH_GMS_STOLEN_8192:
gtt_entries = MB(8) - KB(132); gtt_entries = MB(8) - KB(132);
printk(KERN_INFO PFX "detected %dK stolen memory.\n",gtt_entries / KB(1));
break; break;
case I830_GMCH_GMS_LOCAL: case I830_GMCH_GMS_LOCAL:
rdct = INREG8(intel_i830_private.registers,I830_RDRAM_CHANNEL_TYPE); rdct = INREG8(intel_i830_private.registers,
gtt_entries = (I830_RDRAM_ND(rdct) + 1) * MB(ddt[I830_RDRAM_DDT(rdct)]); I830_RDRAM_CHANNEL_TYPE);
printk(KERN_INFO PFX "detected %dK local memory.\n",gtt_entries / KB(1)); gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
MB(ddt[I830_RDRAM_DDT(rdct)]);
local = 1;
break; break;
default: default:
printk(KERN_INFO PFX "no video memory detected.\n");
gtt_entries = 0; gtt_entries = 0;
break; break;
} }
} else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
gtt_entries = MB(1) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_4M:
gtt_entries = MB(4) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_8M:
gtt_entries = MB(8) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_16M:
gtt_entries = MB(16) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_32M:
gtt_entries = MB(32) - KB(132);
break;
default:
gtt_entries = 0;
break;
}
}
if (gtt_entries > 0)
printk(KERN_INFO PFX "Detected %dK %s memory.\n",
gtt_entries / KB(1), local ? "local" : "stolen");
else
printk(KERN_INFO PFX
"No pre-allocated video memory detected.\n");
gtt_entries /= KB(4); gtt_entries /= KB(4);
intel_i830_private.gtt_entries = gtt_entries; intel_i830_private.gtt_entries = gtt_entries;
...@@ -374,9 +407,18 @@ static int intel_i830_fetch_size(void) ...@@ -374,9 +407,18 @@ static int intel_i830_fetch_size(void)
u16 gmch_ctrl; u16 gmch_ctrl;
struct aper_size_info_fixed *values; struct aper_size_info_fixed *values;
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
values = A_SIZE_FIX(agp_bridge->aperture_sizes); values = A_SIZE_FIX(agp_bridge->aperture_sizes);
if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
/* 855GM/852GM/865G has 128MB aperture size */
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0;
return(values[0].size);
}
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) { if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) values; agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0; agp_bridge->aperture_size_idx = 0;
...@@ -558,6 +600,7 @@ static int __init intel_i830_setup(struct pci_dev *i830_dev) ...@@ -558,6 +600,7 @@ static int __init intel_i830_setup(struct pci_dev *i830_dev)
return(0); return(0);
} }
static int intel_fetch_size(void) static int intel_fetch_size(void)
{ {
int i; int i;
...@@ -1241,7 +1284,7 @@ struct agp_device_ids intel_agp_device_ids[] __initdata = ...@@ -1241,7 +1284,7 @@ struct agp_device_ids intel_agp_device_ids[] __initdata =
{ {
.device_id = PCI_DEVICE_ID_INTEL_82830_HB, .device_id = PCI_DEVICE_ID_INTEL_82830_HB,
.chipset = INTEL_I830_M, .chipset = INTEL_I830_M,
.chipset_name = "i830M", .chipset_name = "830M",
.chipset_setup = intel_830mp_setup .chipset_setup = intel_830mp_setup
}, },
{ {
...@@ -1259,7 +1302,7 @@ struct agp_device_ids intel_agp_device_ids[] __initdata = ...@@ -1259,7 +1302,7 @@ struct agp_device_ids intel_agp_device_ids[] __initdata =
{ {
.device_id = PCI_DEVICE_ID_INTEL_82845G_HB, .device_id = PCI_DEVICE_ID_INTEL_82845G_HB,
.chipset = INTEL_I845_G, .chipset = INTEL_I845_G,
.chipset_name = "i845G", .chipset_name = "845G",
.chipset_setup = intel_845_setup .chipset_setup = intel_845_setup
}, },
{ {
...@@ -1268,12 +1311,24 @@ struct agp_device_ids intel_agp_device_ids[] __initdata = ...@@ -1268,12 +1311,24 @@ struct agp_device_ids intel_agp_device_ids[] __initdata =
.chipset_name = "i850", .chipset_name = "i850",
.chipset_setup = intel_850_setup .chipset_setup = intel_850_setup
}, },
{
.device_id = PCI_DEVICE_ID_INTEL_82855_HB,
.chipset = INTEL_I855_PM,
.chipset_name = "855PM",
.chipset_setup = intel_845_setup
},
{ {
.device_id = PCI_DEVICE_ID_INTEL_82860_HB, .device_id = PCI_DEVICE_ID_INTEL_82860_HB,
.chipset = INTEL_I860, .chipset = INTEL_I860,
.chipset_name = "i860", .chipset_name = "i860",
.chipset_setup = intel_860_setup .chipset_setup = intel_860_setup
}, },
{
.device_id = PCI_DEVICE_ID_INTEL_82865_HB,
.chipset = INTEL_I865_G,
.chipset_name = "865G",
.chipset_setup = intel_845_setup
},
{ }, /* dummy final entry, always present */ { }, /* dummy final entry, always present */
}; };
...@@ -1387,13 +1442,13 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -1387,13 +1442,13 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
if (i810_dev == NULL) { if (i810_dev == NULL) {
/* /*
* We probably have a I845MP chipset with an external graphics * We probably have a I845G chipset with an external graphics
* card. It will be initialized later * card. It will be initialized later
*/ */
agp_bridge->type = INTEL_I845_G; agp_bridge->type = INTEL_I845_G;
break; break;
} }
printk(KERN_INFO PFX "Detected an Intel 845G Chipset.\n"); printk(KERN_INFO PFX "Detected an Intel(R) 845G Chipset.\n");
agp_bridge->type = INTEL_I810; agp_bridge->type = INTEL_I810;
return intel_i830_setup(i810_dev); return intel_i830_setup(i810_dev);
...@@ -1408,7 +1463,63 @@ static int __init agp_find_supported_device(struct pci_dev *dev) ...@@ -1408,7 +1463,63 @@ static int __init agp_find_supported_device(struct pci_dev *dev)
agp_bridge->type = INTEL_I830_M; agp_bridge->type = INTEL_I830_M;
break; break;
} }
printk(KERN_INFO PFX "Detected an Intel 830M Chipset.\n"); printk(KERN_INFO PFX "Detected an Intel(R) 830M Chipset.\n");
agp_bridge->type = INTEL_I810;
return intel_i830_setup(i810_dev);
case PCI_DEVICE_ID_INTEL_82855_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, NULL);
if(i810_dev && PCI_FUNC(i810_dev->devfn) != 0)
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855_IG, i810_dev);
if (i810_dev == NULL) {
/* Intel 855PM with external graphic card */
/* It will be initialized later */
agp_bridge->type = INTEL_I855_PM;
break;
}
{
u32 capval = 0;
const char *name = "855GM/852GM";
pci_read_config_dword(dev, I85X_CAPID, &capval);
switch ((capval >> I85X_VARIANT_SHIFT) &
I85X_VARIANT_MASK) {
case I855_GME:
name = "855GME";
break;
case I855_GM:
name = "855GM";
break;
case I852_GME:
name = "852GME";
break;
case I852_GM:
name = "852GM";
break;
}
printk(KERN_INFO PFX
"Detected an Intel(R) %s Chipset.\n", name);
}
agp_bridge->type = INTEL_I810;
return intel_i830_setup(i810_dev);
case PCI_DEVICE_ID_INTEL_82865_HB:
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82865_IG, NULL);
if (i810_dev && PCI_FUNC(i810_dev->devfn) != 0) {
i810_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
PCI_DEVICE_ID_INTEL_82865_IG, i810_dev);
}
if (i810_dev == NULL) {
/*
* We probably have a 865G chipset with an external graphics
* card. It will be initialized later
*/
agp_bridge->type = INTEL_I865_G;
break;
}
printk(KERN_INFO PFX "Detected an Intel(R) 865G Chipset.\n");
agp_bridge->type = INTEL_I810; agp_bridge->type = INTEL_I810;
return intel_i830_setup(i810_dev); return intel_i830_setup(i810_dev);
......
...@@ -46,6 +46,8 @@ enum chipset_type { ...@@ -46,6 +46,8 @@ enum chipset_type {
INTEL_I820, INTEL_I820,
INTEL_I830_M, INTEL_I830_M,
INTEL_I845_G, INTEL_I845_G,
INTEL_I855_PM,
INTEL_I865_G,
INTEL_I840, INTEL_I840,
INTEL_I845, INTEL_I845,
INTEL_I850, INTEL_I850,
......
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