Dave,

It looks that config space save/restore for intel-agp still has problem
that might affect some chip models. Andreas Mohr's work on his i815 
suspend/resume
support showed that we need to save extra bits in config space on this old chip 
type. 
His patch is in -mm tree, 
http://www.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.22-rc4/2.6.22-rc4-mm2/broken-out/working-3d-dri-intel-agpko-resume-for-i815-chip.patch

And recently James Bottomley also reported that save/restore whole 256 bytes 
config 
space for gfx device can fix his s3 issue on Fujitsu P7120 i915. 
http://lists.freedesktop.org/archives/xorg/2007-June/025346.html

So here's my suggested patch for save whole 256 bytes config space for 
intel-agp,
which could fix these issues. I tested it on my 965GM, that s3 works fine with 
X. 

This patch bases on latest kernel git and my intel-agp patch set on agpgart.git 
tip.
http://git.kernel.org/?p=linux/kernel/git/davej/agpgart.git;a=summary


Signed-off-by: Wang Zhenyu <[EMAIL PROTECTED]>
---
 drivers/char/agp/intel-agp.c |   44 +++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 43 insertions(+), 1 deletions(-)

diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index d383168..bc18241 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -110,6 +110,7 @@ static struct _intel_private {
         * popup and for the GTT.
         */
        int gtt_entries;                        /* i830+ */
+       u32 extra_saved_config[48];     /* suspend/resume */
 } intel_private;
 
 static int intel_i810_fetch_size(void)
@@ -1974,9 +1975,33 @@ static void __devexit agp_intel_remove(struct pci_dev 
*pdev)
 }
 
 #ifdef CONFIG_PM
+static int agp_intel_suspend (struct pci_dev *pdev, pm_message_t state)
+{
+       int i;
+
+       pci_save_state(pdev);
+
+       if (intel_private.pcidev) {
+               pci_save_state(intel_private.pcidev);
+
+               for (i = 0; i < 48; i++)
+                       pci_read_config_dword(intel_private.pcidev, i*4+64,
+                               &intel_private.extra_saved_config[i]);
+
+               pci_set_power_state(intel_private.pcidev,
+                       pci_choose_state(intel_private.pcidev, state));
+       }
+
+       pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+       return 0;
+}
+
 static int agp_intel_resume(struct pci_dev *pdev)
 {
        struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
+       int i = 0;
+       u32 val;
 
        pci_restore_state(pdev);
 
@@ -1984,8 +2009,24 @@ static int agp_intel_resume(struct pci_dev *pdev)
         * as host bridge (00:00) resumes before graphics device (02:00),
         * then our access to its pci space can work right.
         */
-       if (intel_private.pcidev)
+       if (intel_private.pcidev) {
+               pci_set_power_state(intel_private.pcidev, PCI_D0);
                pci_restore_state(intel_private.pcidev);
+               for (i = 0; i < 48; i++) {
+                       pci_read_config_dword(intel_private.pcidev, i*4+64,
+                                               &val);
+                       if (val != intel_private.extra_saved_config[i]) {
+                               printk(KERN_DEBUG "intel-agp: Writing back"
+                                       "config space at offset %x"
+                                       " (was %x, writing %x)\n",
+                                       i*4+64, val,
+                                       intel_private.extra_saved_config[i]);
+                               pci_write_config_dword(intel_private.pcidev,
+                                       i*4+64,
+                                       intel_private.extra_saved_config[i]);
+                       }
+               }
+       }
 
        if (bridge->driver == &intel_generic_driver)
                intel_configure();
@@ -2062,6 +2103,7 @@ static struct pci_driver agp_intel_pci_driver = {
        .probe          = agp_intel_probe,
        .remove         = __devexit_p(agp_intel_remove),
 #ifdef CONFIG_PM
+       .suspend        = agp_intel_suspend,
        .resume         = agp_intel_resume,
 #endif
 };
-- 
1.4.4.4
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to