diff options
author | Ben Widawsky <benjamin.widawsky@intel.com> | 2013-04-08 21:43:54 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-04-18 03:43:15 -0400 |
commit | 6197349bdeb97ee6f533990617c51c67ac233f79 (patch) | |
tree | 8353b6096396903b85a5745e04252429337ec2cd | |
parent | 3ed124b21e6bf388c63b182d9c2d766a6ca0e8be (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.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 114 |
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); | |||
1642 | int __must_check i915_gem_init_hw(struct drm_device *dev); | 1643 | int __must_check i915_gem_init_hw(struct drm_device *dev); |
1643 | void i915_gem_l3_remap(struct drm_device *dev); | 1644 | void i915_gem_l3_remap(struct drm_device *dev); |
1644 | void i915_gem_init_swizzling(struct drm_device *dev); | 1645 | void i915_gem_init_swizzling(struct drm_device *dev); |
1645 | void i915_gem_init_ppgtt(struct drm_device *dev); | ||
1646 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); | 1646 | void i915_gem_cleanup_ringbuffer(struct drm_device *dev); |
1647 | int __must_check i915_gpu_idle(struct drm_device *dev); | 1647 | int __must_check i915_gpu_idle(struct drm_device *dev); |
1648 | int __must_check i915_gem_idle(struct drm_device *dev); | 1648 | int __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 | ||
78 | static 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 */ |
79 | static void gen6_ppgtt_clear_range(struct i915_hw_ppgtt *ppgtt, | 134 | static 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 | ||
282 | void 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 | |||
340 | extern int intel_iommu_gfx_mapped; | 338 | extern 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. |