aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2013-04-08 21:43:54 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-04-18 03:43:15 -0400
commit6197349bdeb97ee6f533990617c51c67ac233f79 (patch)
tree8353b6096396903b85a5745e04252429337ec2cd
parent3ed124b21e6bf388c63b182d9c2d766a6ca0e8be (diff)
drm/i915: Abstract PPGTT enabling
Since we've already set up a nice vtable to abstract other PPGTT functions, also abstract the actual register programming to enable things. This function will probably need to change a bit as we implement real processes. v2: Resolve conflicts due to patch series reordering. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> (v1) Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c3
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c3
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c114
4 files changed, 61 insertions, 61 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index bd92e7d47653..70d10de73bbd 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -927,7 +927,8 @@ int i915_reset(struct drm_device *dev)
927 ring->init(ring); 927 ring->init(ring);
928 928
929 i915_gem_context_init(dev); 929 i915_gem_context_init(dev);
930 i915_gem_init_ppgtt(dev); 930 if (dev_priv->mm.aliasing_ppgtt)
931 dev_priv->mm.aliasing_ppgtt->enable(dev);
931 932
932 /* 933 /*
933 * It would make sense to re-init all the other hw state, at 934 * It would make sense to re-init all the other hw state, at
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 69ddfd1c18f5..c1213213e495 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -449,6 +449,7 @@ struct i915_hw_ppgtt {
449 struct sg_table *st, 449 struct sg_table *st,
450 unsigned int pg_start, 450 unsigned int pg_start,
451 enum i915_cache_level cache_level); 451 enum i915_cache_level cache_level);
452 void (*enable)(struct drm_device *dev);
452 void (*cleanup)(struct i915_hw_ppgtt *ppgtt); 453 void (*cleanup)(struct i915_hw_ppgtt *ppgtt);
453}; 454};
454 455
@@ -1642,7 +1643,6 @@ int __must_check i915_gem_init(struct drm_device *dev);
1642int __must_check i915_gem_init_hw(struct drm_device *dev); 1643int __must_check i915_gem_init_hw(struct drm_device *dev);
1643void i915_gem_l3_remap(struct drm_device *dev); 1644void i915_gem_l3_remap(struct drm_device *dev);
1644void i915_gem_init_swizzling(struct drm_device *dev); 1645void i915_gem_init_swizzling(struct drm_device *dev);
1645void i915_gem_init_ppgtt(struct drm_device *dev);
1646void i915_gem_cleanup_ringbuffer(struct drm_device *dev); 1646void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
1647int __must_check i915_gpu_idle(struct drm_device *dev); 1647int __must_check i915_gpu_idle(struct drm_device *dev);
1648int __must_check i915_gem_idle(struct drm_device *dev); 1648int __must_check i915_gem_idle(struct drm_device *dev);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 63c05ddea612..8a73a68a79ff 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -4029,7 +4029,8 @@ i915_gem_init_hw(struct drm_device *dev)
4029 * contexts before PPGTT. 4029 * contexts before PPGTT.
4030 */ 4030 */
4031 i915_gem_context_init(dev); 4031 i915_gem_context_init(dev);
4032 i915_gem_init_ppgtt(dev); 4032 if (dev_priv->mm.aliasing_ppgtt)
4033 dev_priv->mm.aliasing_ppgtt->enable(dev);
4033 4034
4034 return 0; 4035 return 0;
4035} 4036}
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index b13ba9d53b19..c56de21af910 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -75,6 +75,61 @@ static inline gen6_gtt_pte_t gen6_pte_encode(struct drm_device *dev,
75 return pte; 75 return pte;
76} 76}
77 77
78static void gen6_ppgtt_enable(struct drm_device *dev)
79{
80 drm_i915_private_t *dev_priv = dev->dev_private;
81 uint32_t pd_offset;
82 struct intel_ring_buffer *ring;
83 struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
84 gen6_gtt_pte_t __iomem *pd_addr;
85 uint32_t pd_entry;
86 int i;
87
88 pd_addr = (gen6_gtt_pte_t __iomem*)dev_priv->gtt.gsm +
89 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
90 for (i = 0; i < ppgtt->num_pd_entries; i++) {
91 dma_addr_t pt_addr;
92
93 pt_addr = ppgtt->pt_dma_addr[i];
94 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
95 pd_entry |= GEN6_PDE_VALID;
96
97 writel(pd_entry, pd_addr + i);
98 }
99 readl(pd_addr);
100
101 pd_offset = ppgtt->pd_offset;
102 pd_offset /= 64; /* in cachelines, */
103 pd_offset <<= 16;
104
105 if (INTEL_INFO(dev)->gen == 6) {
106 uint32_t ecochk, gab_ctl, ecobits;
107
108 ecobits = I915_READ(GAC_ECO_BITS);
109 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
110
111 gab_ctl = I915_READ(GAB_CTL);
112 I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT);
113
114 ecochk = I915_READ(GAM_ECOCHK);
115 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT |
116 ECOCHK_PPGTT_CACHE64B);
117 I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
118 } else if (INTEL_INFO(dev)->gen >= 7) {
119 I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B);
120 /* GFX_MODE is per-ring on gen7+ */
121 }
122
123 for_each_ring(ring, dev_priv, i) {
124 if (INTEL_INFO(dev)->gen >= 7)
125 I915_WRITE(RING_MODE_GEN7(ring),
126 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
127
128 I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
129 I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
130 }
131}
132
78/* PPGTT support for Sandybdrige/Gen6 and later */ 133/* PPGTT support for Sandybdrige/Gen6 and later */
79static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, 134static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt,
80 unsigned first_entry, 135 unsigned first_entry,
@@ -168,6 +223,7 @@ static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
168 gtt_total_entries(dev_priv->gtt) - I915_PPGTT_PD_ENTRIES; 223 gtt_total_entries(dev_priv->gtt) - I915_PPGTT_PD_ENTRIES;
169 224
170 ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES; 225 ppgtt->num_pd_entries = I915_PPGTT_PD_ENTRIES;
226 ppgtt->enable = gen6_ppgtt_enable;
171 ppgtt->clear_range = gen6_ppgtt_clear_range; 227 ppgtt->clear_range = gen6_ppgtt_clear_range;
172 ppgtt->insert_entries = gen6_ppgtt_insert_entries; 228 ppgtt->insert_entries = gen6_ppgtt_insert_entries;
173 ppgtt->cleanup = gen6_ppgtt_cleanup; 229 ppgtt->cleanup = gen6_ppgtt_cleanup;
@@ -279,64 +335,6 @@ void i915_ppgtt_unbind_object(struct i915_hw_ppgtt *ppgtt,
279 obj->base.size >> PAGE_SHIFT); 335 obj->base.size >> PAGE_SHIFT);
280} 336}
281 337
282void i915_gem_init_ppgtt(struct drm_device *dev)
283{
284 drm_i915_private_t *dev_priv = dev->dev_private;
285 uint32_t pd_offset;
286 struct intel_ring_buffer *ring;
287 struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
288 gen6_gtt_pte_t __iomem *pd_addr;
289 uint32_t pd_entry;
290 int i;
291
292 if (!dev_priv->mm.aliasing_ppgtt)
293 return;
294
295 pd_addr = (gen6_gtt_pte_t __iomem *)dev_priv->gtt.gsm +
296 ppgtt->pd_offset / sizeof(gen6_gtt_pte_t);
297 for (i = 0; i < ppgtt->num_pd_entries; i++) {
298 dma_addr_t pt_addr;
299
300 pt_addr = ppgtt->pt_dma_addr[i];
301 pd_entry = GEN6_PDE_ADDR_ENCODE(pt_addr);
302 pd_entry |= GEN6_PDE_VALID;
303
304 writel(pd_entry, pd_addr + i);
305 }
306 readl(pd_addr);
307
308 pd_offset = ppgtt->pd_offset;
309 pd_offset /= 64; /* in cachelines, */
310 pd_offset <<= 16;
311
312 if (INTEL_INFO(dev)->gen == 6) {
313 uint32_t ecochk, gab_ctl, ecobits;
314
315 ecobits = I915_READ(GAC_ECO_BITS);
316 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
317
318 gab_ctl = I915_READ(GAB_CTL);
319 I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT);
320
321 ecochk = I915_READ(GAM_ECOCHK);
322 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT |
323 ECOCHK_PPGTT_CACHE64B);
324 I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
325 } else if (INTEL_INFO(dev)->gen >= 7) {
326 I915_WRITE(GAM_ECOCHK, ECOCHK_PPGTT_CACHE64B);
327 /* GFX_MODE is per-ring on gen7+ */
328 }
329
330 for_each_ring(ring, dev_priv, i) {
331 if (INTEL_INFO(dev)->gen >= 7)
332 I915_WRITE(RING_MODE_GEN7(ring),
333 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
334
335 I915_WRITE(RING_PP_DIR_DCLV(ring), PP_DIR_DCLV_2G);
336 I915_WRITE(RING_PP_DIR_BASE(ring), pd_offset);
337 }
338}
339
340extern int intel_iommu_gfx_mapped; 338extern int intel_iommu_gfx_mapped;
341/* Certain Gen5 chipsets require require idling the GPU before 339/* Certain Gen5 chipsets require require idling the GPU before
342 * unmapping anything from the GTT when VT-d is enabled. 340 * unmapping anything from the GTT when VT-d is enabled.