aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2011-03-23 14:16:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-03-23 22:45:06 -0400
commit968b503e69a6b90aa4a3b9162960f605b6abd821 (patch)
treeb11144867500373dc33b1d85413dbf575e849c90
parent4bbba111d94781d34081c37856bbc5eb33f6c72a (diff)
Revert "drm/i915: Don't save/restore hardware status page address register"
This reverts commit a7a75c8f70d6f6a2f16c9f627f938bbee2d32718. There are two different variations on how Intel hardware addresses the "Hardware Status Page". One as a location in physical memory and the other as an offset into the virtual memory of the GPU, used in more recent chipsets. (The HWS itself is a cacheable region of memory which the GPU can write to without requiring CPU synchronisation, used for updating various details of hardware state, such as the position of the GPU head in the ringbuffer, the last breadcrumb seqno, etc). These two types of addresses were updated in different locations of code - one inline with the ringbuffer initialisation, and the other during device initialisation. (The HWS page is logically associated with the rings, and there is one HWS page per ring.) During resume, only the ringbuffers were being re-initialised along with the virtual HWS page, leaving the older physical address HWS untouched. This then caused a hang on the older gen3/4 (915GM, 945GM, 965GM) the first time we tried to synchronise the GPU as the breadcrumbs were never being updated. Reported-and-tested-by: Linus Torvalds <torvalds@linux-foundation.org> Reported-by: Jan Niehusmann <jan@gondor.com> Reported-by: Justin P. Mattock <justinmattock@gmail.com> Reported-and-tested-by: Michael "brot" Groh <brot@minad.de> Cc: Zhenyu Wang <zhenyuw@linux.intel.com> Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h1
-rw-r--r--drivers/gpu/drm/i915/i915_suspend.c6
2 files changed, 7 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 449650545bb..5004724ea57 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -383,6 +383,7 @@ typedef struct drm_i915_private {
383 u32 saveDSPACNTR; 383 u32 saveDSPACNTR;
384 u32 saveDSPBCNTR; 384 u32 saveDSPBCNTR;
385 u32 saveDSPARB; 385 u32 saveDSPARB;
386 u32 saveHWS;
386 u32 savePIPEACONF; 387 u32 savePIPEACONF;
387 u32 savePIPEBCONF; 388 u32 savePIPEBCONF;
388 u32 savePIPEASRC; 389 u32 savePIPEASRC;
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index 7e992a8e909..da474153a0a 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -796,6 +796,9 @@ int i915_save_state(struct drm_device *dev)
796 796
797 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); 797 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
798 798
799 /* Hardware status page */
800 dev_priv->saveHWS = I915_READ(HWS_PGA);
801
799 i915_save_display(dev); 802 i915_save_display(dev);
800 803
801 /* Interrupt state */ 804 /* Interrupt state */
@@ -842,6 +845,9 @@ int i915_restore_state(struct drm_device *dev)
842 845
843 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); 846 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
844 847
848 /* Hardware status page */
849 I915_WRITE(HWS_PGA, dev_priv->saveHWS);
850
845 i915_restore_display(dev); 851 i915_restore_display(dev);
846 852
847 /* Interrupt state */ 853 /* Interrupt state */