]> err.no Git - linux-2.6/commitdiff
[PATCH] agp: restore APBASE after setting APSIZE
authorMatthew Garrett <mjg59@srcf.ucam.org>
Fri, 29 Jul 2005 21:03:39 +0000 (14:03 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Fri, 29 Jul 2005 22:01:15 +0000 (15:01 -0700)
When leaving S3 state, the AGP bridge may not have all PCI configuration
registers set in the same way as they were at boot.  This should be fixed
by pci_restore_state - however, the APBASE register cannot be set to
conflict with the APSIZE register.  If APSIZE is larger than it was before
suspend, pci_restore_state will not restore APBASE correctly.  The attached
patch adds an extra item to the agp_bridge_data structure and uses it to
store the value of APBASE.  On resume, this is then written after APSIZE
has been set.  This patch only touches the path used for Intel chipsets
without integrated graphics, and may need to be extended to work with the
others.

Without this patch, I get the symptoms described in bug 4921 - APBASE ends
up overlapping various PCI devices, and as a result they fail to work after
resume.

Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org>
Acked-by: Dave Jones <davej@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/char/agp/agp.h
drivers/char/agp/intel-agp.c

index c1fe013c64f34c31c1d9b9cceded9d0d2b51ad08..b4af87c6f9c80fbf30e6adf574c8a34af11f4588 100644 (file)
@@ -143,6 +143,7 @@ struct agp_bridge_data {
        char major_version;
        char minor_version;
        struct list_head list;
+       u32 apbase_config;
 };
 
 #define KB(x)  ((x) * 1024)
index 51266d6b4d78af9bf138f52dbbdf6f43413ac0c7..1f7d415f432ca4f94a7b9f6dc0b3f531df3fa52d 100644 (file)
@@ -1047,9 +1047,15 @@ static int intel_845_configure(void)
        /* aperture size */
        pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
 
-       /* address to map to */
-       pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
-       agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+       if (agp_bridge->apbase_config != 0) {
+               pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
+                                      agp_bridge->apbase_config);
+       } else {
+               /* address to map to */
+               pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
+               agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
+               agp_bridge->apbase_config = temp;
+       }
 
        /* attbase - aperture base */
        pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);