aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-03-21 19:14:43 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-04-01 06:25:29 -0400
commit55a254ac63a3ac1867d1501030e7fba69c7d4aeb (patch)
treea0438e133793dcce412879537d49214c29a8fefd /drivers/gpu
parentf47166d2b0001fcb752b40c5a2d4db986dfbea68 (diff)
drm/i915: properly restore the ppgtt page directory on resume
The ppgtt page directory lives in a snatched part of the gtt pte range. Which naturally gets cleared on hibernate when we pull the power. Suspend to ram (which is what I've tested) works because despite the fact that this is a mmio region, it is actually back by system ram. Fix this by moving the page directory setup code to the ppgtt init code (which gets called on resume). This fixes hibernate on my ivb and snb. Reviewed-by: Ben Widawsky <ben@bwidawsk.net> Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c22
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c9
2 files changed, 21 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 1f441f5c2405..97e659985223 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -3754,12 +3754,32 @@ void i915_gem_init_ppgtt(struct drm_device *dev)
3754 drm_i915_private_t *dev_priv = dev->dev_private; 3754 drm_i915_private_t *dev_priv = dev->dev_private;
3755 uint32_t pd_offset; 3755 uint32_t pd_offset;
3756 struct intel_ring_buffer *ring; 3756 struct intel_ring_buffer *ring;
3757 struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
3758 uint32_t __iomem *pd_addr;
3759 uint32_t pd_entry;
3757 int i; 3760 int i;
3758 3761
3759 if (!dev_priv->mm.aliasing_ppgtt) 3762 if (!dev_priv->mm.aliasing_ppgtt)
3760 return; 3763 return;
3761 3764
3762 pd_offset = dev_priv->mm.aliasing_ppgtt->pd_offset; 3765
3766 pd_addr = dev_priv->mm.gtt->gtt + ppgtt->pd_offset/sizeof(uint32_t);
3767 for (i = 0; i < ppgtt->num_pd_entries; i++) {
3768 dma_addr_t pt_addr;
3769
3770 if (dev_priv->mm.gtt->needs_dmar)
3771 pt_addr = ppgtt->pt_dma_addr[i];
3772 else
3773 pt_addr = page_to_phys(ppgtt->pt_pages[i]);
3774
3775 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
3776 pd_entry |= GEN6_PDE_VALID;
3777
3778 writel(pd_entry, pd_addr + i);
3779 }
3780 readl(pd_addr);
3781
3782 pd_offset = ppgtt->pd_offset;
3763 pd_offset /= 64; /* in cachelines, */ 3783 pd_offset /= 64; /* in cachelines, */
3764 pd_offset <<= 16; 3784 pd_offset <<= 16;
3765 3785
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 2eacd78bb93b..a135c61f4119 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -65,9 +65,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
65{ 65{
66 struct drm_i915_private *dev_priv = dev->dev_private; 66 struct drm_i915_private *dev_priv = dev->dev_private;
67 struct i915_hw_ppgtt *ppgtt; 67 struct i915_hw_ppgtt *ppgtt;
68 uint32_t pd_entry;
69 unsigned first_pd_entry_in_global_pt; 68 unsigned first_pd_entry_in_global_pt;
70 uint32_t __iomem *pd_addr;
71 int i; 69 int i;
72 int ret = -ENOMEM; 70 int ret = -ENOMEM;
73 71
@@ -100,7 +98,6 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
100 goto err_pt_alloc; 98 goto err_pt_alloc;
101 } 99 }
102 100
103 pd_addr = dev_priv->mm.gtt->gtt + first_pd_entry_in_global_pt;
104 for (i = 0; i < ppgtt->num_pd_entries; i++) { 101 for (i = 0; i < ppgtt->num_pd_entries; i++) {
105 dma_addr_t pt_addr; 102 dma_addr_t pt_addr;
106 if (dev_priv->mm.gtt->needs_dmar) { 103 if (dev_priv->mm.gtt->needs_dmar) {
@@ -117,13 +114,7 @@ int i915_gem_init_aliasing_ppgtt(struct drm_device *dev)
117 ppgtt->pt_dma_addr[i] = pt_addr; 114 ppgtt->pt_dma_addr[i] = pt_addr;
118 } else 115 } else
119 pt_addr = page_to_phys(ppgtt->pt_pages[i]); 116 pt_addr = page_to_phys(ppgtt->pt_pages[i]);
120
121 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
122 pd_entry |= GEN6_PDE_VALID;
123
124 writel(pd_entry, pd_addr + i);
125 } 117 }
126 readl(pd_addr);
127 118
128 ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma; 119 ppgtt->scratch_page_dma_addr = dev_priv->mm.gtt->scratch_page_dma;
129 120