aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorMatthew Garrett <mjg59@srcf.ucam.org>2005-07-29 17:03:39 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-29 18:01:15 -0400
commitb0825488a642cadcf39709961dde61440cb0731c (patch)
treecd73116cb0298a6333cbfda8ba2874b1ff180e05 /drivers/char
parentb87a1e506115e7df4c6bfd266267ee0088cba3b7 (diff)
[PATCH] agp: restore APBASE after setting APSIZE
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>
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/agp/agp.h1
-rw-r--r--drivers/char/agp/intel-agp.c12
2 files changed, 10 insertions, 3 deletions
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index c1fe013c64f3..b4af87c6f9c8 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -143,6 +143,7 @@ struct agp_bridge_data {
143 char major_version; 143 char major_version;
144 char minor_version; 144 char minor_version;
145 struct list_head list; 145 struct list_head list;
146 u32 apbase_config;
146}; 147};
147 148
148#define KB(x) ((x) * 1024) 149#define KB(x) ((x) * 1024)
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index 51266d6b4d78..1f7d415f432c 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -1047,9 +1047,15 @@ static int intel_845_configure(void)
1047 /* aperture size */ 1047 /* aperture size */
1048 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value); 1048 pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
1049 1049
1050 /* address to map to */ 1050 if (agp_bridge->apbase_config != 0) {
1051 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp); 1051 pci_write_config_dword(agp_bridge->dev, AGP_APBASE,
1052 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); 1052 agp_bridge->apbase_config);
1053 } else {
1054 /* address to map to */
1055 pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
1056 agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
1057 agp_bridge->apbase_config = temp;
1058 }
1053 1059
1054 /* attbase - aperture base */ 1060 /* attbase - aperture base */
1055 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr); 1061 pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);