Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 122

kernel-2.6.18-238.el5.src.rpm

From: Geoff Gustafson <lkml@twopenguins.org>
Subject: [RHEL5.1 PATCH] agpgart fixes and new pci ids (bz 227391)
Date: Mon, 09 Apr 2007 17:40:30 -0400
Bugzilla: 227391
Message-Id: <461AB2CE.8090603@twopenguins.org>
Changelog: [agp] agpgart fixes and new pci ids


This patch backports three upstream agpgart fixes plus PCI IDs posted 
yesterday, all needed to support the 965GM (Crestline) chipset graphics 
from Intel. The graphics driver backports are not finished but this has 
been tested by Intel with an early version. I built it against 14.EL5 
and sanity checked it.

- fixes detection of aperture size versus GTT size on G965
- restore graphics device's pci space early in resume
- don't try to remap i810 registers on resume
- new PCI IDs for 965GM graphics

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=c41e0deb50c44f9d119c2268f1be05e6a6bb5772
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4b95320fc4d21b0ff2f8604305dd6c851aff6096
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=e4ac5e4f55f55b16e084a46b1b8e233f490ba701
http://marc.info/?l=linux-kernel&m=117607982308247&w=2

- Geoff



diff -Naurp linux-2.6.18.i386/drivers/char/agp/agp.h linux-2.6.18.i386-backport-agp/drivers/char/agp/agp.h
--- linux-2.6.18.i386/drivers/char/agp/agp.h	2007-03-31 02:37:38.000000000 +0800
+++ linux-2.6.18.i386-backport-agp/drivers/char/agp/agp.h	2007-03-31 02:25:24.000000000 +0800
@@ -225,6 +225,10 @@ struct agp_bridge_data {
 #define I810_GMS_DISABLE	0x00000000
 #define I810_PGETBL_CTL		0x2020
 #define I810_PGETBL_ENABLED	0x00000001
+#define I965_PGETBL_SIZE_MASK	0x0000000e
+#define I965_PGETBL_SIZE_512KB	(0 << 1)
+#define I965_PGETBL_SIZE_256KB	(1 << 1)
+#define I965_PGETBL_SIZE_128KB	(2 << 1)
 #define I810_DRAM_CTL		0x3000
 #define I810_DRAM_ROW_0		0x00000001
 #define I810_DRAM_ROW_0_SDRAM	0x00000001
diff -Naurp linux-2.6.18.i386/drivers/char/agp/intel-agp.c linux-2.6.18.i386-backport-agp/drivers/char/agp/intel-agp.c
--- linux-2.6.18.i386/drivers/char/agp/intel-agp.c	2007-03-31 02:37:38.000000000 +0800
+++ linux-2.6.18.i386-backport-agp/drivers/char/agp/intel-agp.c	2007-03-31 02:25:25.000000000 +0800
@@ -17,11 +17,14 @@
 #define PCI_DEVICE_ID_INTEL_82965Q_IG       0x2992
 #define PCI_DEVICE_ID_INTEL_82965G_HB       0x29A0
 #define PCI_DEVICE_ID_INTEL_82965G_IG       0x29A2
+#define PCI_DEVICE_ID_INTEL_82965GM_HB      0x2A00
+#define PCI_DEVICE_ID_INTEL_82965GM_IG      0x2A02
 
 #define IS_I965 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82946GZ_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_1_HB || \
                  agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965Q_HB || \
-                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB)
+                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965G_HB || \
+                 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82965GM_HB)
 
 
 /* Intel 815 register */
@@ -117,13 +120,15 @@ static int intel_i810_configure(void)
 
 	current_size = A_SIZE_FIX(agp_bridge->current_size);
 
-	pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
-	temp &= 0xfff80000;
-
-	intel_i810_private.registers = ioremap(temp, 128 * 4096);
 	if (!intel_i810_private.registers) {
-		printk(KERN_ERR PFX "Unable to remap memory.\n");
-		return -ENOMEM;
+		pci_read_config_dword(intel_i810_private.i810_dev, I810_MMADDR, &temp);
+		temp &= 0xfff80000;
+
+		intel_i810_private.registers = ioremap(temp, 128 * 4096);
+		if (!intel_i810_private.registers) {
+			printk(KERN_ERR PFX "Unable to remap memory.\n");
+			return -ENOMEM;
+		}
 	}
 
 	if ((readl(intel_i810_private.registers+I810_DRAM_CTL)
@@ -370,6 +375,11 @@ static struct _intel_i830_private {
 	struct pci_dev *i830_dev;		/* device one */
 	volatile u8 __iomem *registers;
 	volatile u32 __iomem *gtt;		/* I915G */
+	/* gtt_entries is the number of gtt entries that are already mapped
+	* to stolen memory.  Stolen memory is larger than the memory mapped
+	* through gtt_entries, as it includes some reserved space for the BIOS
+	* popup and for the GTT.
+	*/
 	int gtt_entries;
 } intel_i830_private;
 
@@ -380,14 +390,41 @@ static void intel_i830_init_gtt_entries(
 	u8 rdct;
 	int local = 0;
 	static const int ddt[4] = { 0, 16, 32, 64 };
-	int size;
+	int size;/* reserved space (in kb) at the top of stolen memory */
 
 	pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
 
-	/* We obtain the size of the GTT, which is also stored (for some
-	 * reason) at the top of stolen memory. Then we add 4KB to that
-	 * for the video BIOS popup, which is also stored in there. */
-	size = agp_bridge->driver->fetch_size() + 4;
+	if (IS_I965) {
+		u32 pgetbl_ctl;
+
+		pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
+                                     &pgetbl_ctl);
+		/* The 965 has a field telling us the size of the GTT,
+		* which may be larger than what is necessary to map the
+		* aperture.
+		*/
+		switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) {
+		case I965_PGETBL_SIZE_128KB:
+			size = 128;
+			break;
+		case I965_PGETBL_SIZE_256KB:
+			size = 256;
+			break;
+		case I965_PGETBL_SIZE_512KB:
+			size = 512;
+			break;
+		default:
+			printk(KERN_INFO PFX "Unknown page table size, "
+				"assuming 512KB\n");
+			size = 512;
+		}
+		size += 4; /* add in BIOS popup space */
+	} else {
+		/* On previous hardware, the GTT size was just what was
+		* required to map the aperture.
+		*/
+		size = agp_bridge->driver->fetch_size() + 4;
+	}
 
 	if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
 	    agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
@@ -743,22 +780,27 @@ static int intel_i915_remove_entries(str
 	return 0;
 }
 
-static int intel_i915_fetch_size(void)
+/* Return the aperture size by just checking the resource length.  The effect
+ * described in the spec of the MSAC registers is just changing of the
+ * resource size.
+ */
+static int intel_i9xx_fetch_size(void)
 {
-	struct aper_size_info_fixed *values;
-	u32 temp, offset;
+	int num_sizes = sizeof(intel_i830_sizes) / sizeof(*intel_i830_sizes);
+	int aper_size; /* size in megabytes */
+	int i;
 
-#define I915_256MB_ADDRESS_MASK (1<<27)
+	aper_size = pci_resource_len(intel_i830_private.i830_dev, 2) / MB(1);
 
-	values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
+	for (i = 0; i < num_sizes; i++) {
+		if (aper_size == intel_i830_sizes[i].size) {
+			agp_bridge->current_size = intel_i830_sizes + i;
+			agp_bridge->previous_size = agp_bridge->current_size;
+			return aper_size;
+		}
+	}	
 
-	pci_read_config_dword(intel_i830_private.i830_dev, I915_GMADDR, &temp);
-	if (temp & I915_256MB_ADDRESS_MASK)
-		offset = 0;	/* 128MB aperture */
-	else
-		offset = 2;	/* 256MB aperture */
-	agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
-	return values[offset].size;
+	return 0;
 }
 
 /* The intel i915 automatically initializes the agp aperture during POST.
@@ -821,37 +863,6 @@ static unsigned long intel_i965_mask_mem
 	return addr | bridge->driver->masks[type].mask;
 }
 
-static int intel_i965_fetch_size(void)
-{
-       struct aper_size_info_fixed *values;
-       u32 offset = 0;
-       u8 temp;
-
-#define I965_512MB_ADDRESS_MASK (3<<1)
-
-       values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
-
-       pci_read_config_byte(intel_i830_private.i830_dev, I965_MSAC, &temp);
-       temp &= I965_512MB_ADDRESS_MASK;
-       switch (temp) {
-       case 0x00:
-               offset = 0; /* 128MB */
-               break;
-       case 0x06:
-               offset = 3; /* 512MB */
-               break;
-       default:
-       case 0x02:
-               offset = 2; /* 256MB */
-               break;
-       }
-
-       agp_bridge->previous_size = agp_bridge->current_size = (void *)(values + offset);
-
-	/* The i965 GTT is always sized as if it had a 512kB aperture size */
-	return 512;
-}
-
 /* The intel i965 automatically initializes the agp aperture during POST.
 + * Use the memory already set aside for in the GTT.
 + */
@@ -1574,7 +1585,7 @@ static struct agp_bridge_driver intel_91
 	.num_aperture_sizes	= 4,
 	.needs_scratch_page	= TRUE,
 	.configure		= intel_i915_configure,
-	.fetch_size		= intel_i915_fetch_size,
+	.fetch_size		= intel_i9xx_fetch_size,
 	.cleanup		= intel_i915_cleanup,
 	.tlb_flush		= intel_i810_tlbflush,
 	.mask_memory		= intel_i810_mask_memory,
@@ -1598,7 +1609,7 @@ static struct agp_bridge_driver intel_i9
        .num_aperture_sizes     = 4,
        .needs_scratch_page     = TRUE,
        .configure              = intel_i915_configure,
-       .fetch_size             = intel_i965_fetch_size,
+       .fetch_size             = intel_i9xx_fetch_size,
        .cleanup                = intel_i915_cleanup,
        .tlb_flush              = intel_i810_tlbflush,
        .mask_memory            = intel_i965_mask_memory,
@@ -1837,6 +1848,13 @@ static int __devinit agp_intel_probe(str
 			bridge->driver = &intel_845_driver;
 		name = "965G";
 		break;
+	case PCI_DEVICE_ID_INTEL_82965GM_HB:
+		if (find_i830(PCI_DEVICE_ID_INTEL_82965GM_IG))
+			bridge->driver = &intel_i965_driver;
+		else
+			bridge->driver = &intel_845_driver;
+		name = "965GM";
+		break;
 
 	case PCI_DEVICE_ID_INTEL_7505_0:
 		bridge->driver = &intel_7505_driver;
@@ -1927,6 +1945,15 @@ static int agp_intel_resume(struct pci_d
 
 	pci_restore_state(pdev);
 
+	/* We should restore our graphics device's config space,
+	* as host bridge (00:00) resumes before graphics device (02:00),
+	* then our access to its pci space can work right. 
+	*/
+	if (intel_i810_private.i810_dev)
+		pci_restore_state(intel_i810_private.i810_dev);
+	if (intel_i830_private.i830_dev)
+		pci_restore_state(intel_i830_private.i830_dev);
+
 	if (bridge->driver == &intel_generic_driver)
 		intel_configure();
 	else if (bridge->driver == &intel_850_driver)
@@ -1987,6 +2014,7 @@ static struct pci_device_id agp_intel_pc
 	ID(PCI_DEVICE_ID_INTEL_82965G_1_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965Q_HB),
 	ID(PCI_DEVICE_ID_INTEL_82965G_HB),
+	ID(PCI_DEVICE_ID_INTEL_82965GM_HB),
 	{ }
 };
 

On G965, I810_PGETBL_CTL is a mmio offset, but we wrongly take it
as pci config space offset in detecting GTT size. This one line patch
fixs this.

Signed-off-by: Wang Zhenyu <zhenyu.z.wang@intel.com>

---
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index a9fdbf9..4c05c71 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -431,9 +431,8 @@ static void intel_i830_init_gtt_entries(
 
 	if (IS_I965) {
 		u32 pgetbl_ctl;
-
-		pci_read_config_dword(agp_bridge->dev, I810_PGETBL_CTL,
-                                     &pgetbl_ctl);
+		pgetbl_ctl = readl(intel_i830_private.registers+I810_PGETBL_CTL);
+
 		/* The 965 has a field telling us the size of the GTT,
 		 * which may be larger than what is necessary to map the
 		 * aperture.