aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Widawsky <benjamin.widawsky@intel.com>2013-11-05 01:29:36 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-11-08 12:09:47 -0500
commit94e409c1449858b893c55d22f4e9ea9e845a91ed (patch)
tree5801fb8edaabd2974abcb2af36996599ed0905b2
parent9df15b499b083821b5e93fda8766b4e8eeabcd2b (diff)
drm/i915/bdw: Implement PPGTT enable
Legacy PPGTT on GEN8 requires programming 4 PDP registers per ring. Since all rings are using the same address space with the current code the logic is simply to program all the tables we've setup for the PPGTT. v2: Turn on PPGTT in GFX_MODE v3: v2 was the wrong patch v4: Resolve conflicts due to patch series reordering. v5: Squash in fixup from Ben: Use LRI to write PDPs The docs (and simulator seems to back up) suggest that we can only program legacy PPGTT PDPs with LRI commands. v6: Rebase around context differences conflicts. v7: Use #defines for per ring PDPs. (Damien) v8: Don't use typede'f private_t. Signed-off-by: Ben Widawsky <ben@bwidawsk.net> (up to v3 and v7) Reviewed-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_gem_gtt.c50
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h3
2 files changed, 53 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
index 39bfaf290a95..60f398183c87 100644
--- a/drivers/gpu/drm/i915/i915_gem_gtt.c
+++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
@@ -195,6 +195,55 @@ static gen6_gtt_pte_t iris_pte_encode(dma_addr_t addr,
195 return pte; 195 return pte;
196} 196}
197 197
198/* Broadwell Page Directory Pointer Descriptors */
199static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry,
200 uint64_t val)
201{
202 int ret;
203
204 BUG_ON(entry >= 4);
205
206 ret = intel_ring_begin(ring, 6);
207 if (ret)
208 return ret;
209
210 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
211 intel_ring_emit(ring, GEN8_RING_PDP_UDW(ring, entry));
212 intel_ring_emit(ring, (u32)(val >> 32));
213 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
214 intel_ring_emit(ring, GEN8_RING_PDP_LDW(ring, entry));
215 intel_ring_emit(ring, (u32)(val));
216 intel_ring_advance(ring);
217
218 return 0;
219}
220
221static int gen8_ppgtt_enable(struct drm_device *dev)
222{
223 struct drm_i915_private *dev_priv = dev->dev_private;
224 struct intel_ring_buffer *ring;
225 struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt;
226 int i, j, ret;
227
228 /* bit of a hack to find the actual last used pd */
229 int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE;
230
231 for_each_ring(ring, dev_priv, j) {
232 I915_WRITE(RING_MODE_GEN7(ring),
233 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
234 }
235
236 for (i = used_pd - 1; i >= 0; i--) {
237 dma_addr_t addr = ppgtt->pd_dma_addr[i];
238 for_each_ring(ring, dev_priv, j) {
239 ret = gen8_write_pdp(ring, i, addr);
240 if (ret)
241 return ret;
242 }
243 }
244 return 0;
245}
246
198static void gen8_ppgtt_clear_range(struct i915_address_space *vm, 247static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
199 unsigned first_entry, 248 unsigned first_entry,
200 unsigned num_entries, 249 unsigned num_entries,
@@ -326,6 +375,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size)
326 ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); 375 ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT);
327 ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); 376 ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT);
328 ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; 377 ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE;
378 ppgtt->enable = gen8_ppgtt_enable;
329 ppgtt->base.clear_range = gen8_ppgtt_clear_range; 379 ppgtt->base.clear_range = gen8_ppgtt_clear_range;
330 ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; 380 ppgtt->base.insert_entries = gen8_ppgtt_insert_entries;
331 ppgtt->base.cleanup = gen8_ppgtt_cleanup; 381 ppgtt->base.cleanup = gen8_ppgtt_cleanup;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 132b5d083df8..d186c779aa2e 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -110,6 +110,9 @@
110#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220) 110#define RING_PP_DIR_DCLV(ring) ((ring)->mmio_base+0x220)
111#define PP_DIR_DCLV_2G 0xffffffff 111#define PP_DIR_DCLV_2G 0xffffffff
112 112
113#define GEN8_RING_PDP_UDW(ring, n) ((ring)->mmio_base+0x270 + ((n) * 8 + 4))
114#define GEN8_RING_PDP_LDW(ring, n) ((ring)->mmio_base+0x270 + (n) * 8)
115
113#define GAM_ECOCHK 0x4090 116#define GAM_ECOCHK 0x4090
114#define ECOCHK_SNB_BIT (1<<10) 117#define ECOCHK_SNB_BIT (1<<10)
115#define HSW_ECOCHK_ARB_PRIO_SOL (1<<6) 118#define HSW_ECOCHK_ARB_PRIO_SOL (1<<6)