Message ID | 1383451680-11173-28-git-send-email-benjamin.widawsky@intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Sat, Nov 02, 2013 at 09:07:25PM -0700, Ben Widawsky wrote: > 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. > > v4: Rebase around context differences conflicts. > > Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> > Signed-off-by: Ben Widawsky <ben@bwidawsk.net> (v3) > Reviewed-by: Imre Deak <imre.deak@intel.com> > Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> The bikeshed is a welcomed documentation addition (in a separate patch or not) Reviewed-by: Damien Lespiau <damien.lespiau@intel.com> > --- > drivers/gpu/drm/i915/i915_gem_gtt.c | 50 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 50 insertions(+) > > diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c > index 27e157d..07892e2 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, > return pte; > } > > +/* Broadwell Page Directory Pointer Descriptors */ > +static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry, > + uint64_t val) > +{ > + int ret; > + > + BUG_ON(entry >= 4); > + > + ret = intel_ring_begin(ring, 6); > + if (ret) > + return ret; > + > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > + intel_ring_emit(ring, ring->mmio_base + 0x270 + (entry * 8) + 4); > + intel_ring_emit(ring, (u32)(val >> 32)); > + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); > + intel_ring_emit(ring, ring->mmio_base + 0x270 + (entry * 8)); > + intel_ring_emit(ring, (u32)(val)); > + intel_ring_advance(ring); Could use a per ring define for this register (which is PDP0 afaict). > + > + return 0; > +} > + > +static int gen8_ppgtt_enable(struct drm_device *dev) > +{ > + drm_i915_private_t *dev_priv = dev->dev_private; > + struct intel_ring_buffer *ring; > + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; > + int i, j, ret; > + > + /* bit of a hack to find the actual last used pd */ > + int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE; > + > + for_each_ring(ring, dev_priv, j) { > + I915_WRITE(RING_MODE_GEN7(ring), > + _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); > + } > + > + for (i = used_pd - 1; i >= 0; i--) { > + dma_addr_t addr = ppgtt->pd_dma_addr[i]; > + for_each_ring(ring, dev_priv, j) { > + ret = gen8_write_pdp(ring, i, addr); > + if (ret) > + return ret; > + } > + } > + return 0; > +} > + > static void gen8_ppgtt_clear_range(struct i915_address_space *vm, > unsigned first_entry, > unsigned num_entries, > @@ -326,6 +375,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) > ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); > ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); > ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; > + ppgtt->enable = gen8_ppgtt_enable; > ppgtt->base.clear_range = gen8_ppgtt_clear_range; > ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; > ppgtt->base.cleanup = gen8_ppgtt_cleanup; > -- > 1.8.4.2 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 27e157d..07892e2 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, return pte; } +/* Broadwell Page Directory Pointer Descriptors */ +static int gen8_write_pdp(struct intel_ring_buffer *ring, unsigned entry, + uint64_t val) +{ + int ret; + + BUG_ON(entry >= 4); + + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, ring->mmio_base + 0x270 + (entry * 8) + 4); + intel_ring_emit(ring, (u32)(val >> 32)); + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, ring->mmio_base + 0x270 + (entry * 8)); + intel_ring_emit(ring, (u32)(val)); + intel_ring_advance(ring); + + return 0; +} + +static int gen8_ppgtt_enable(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; + struct i915_hw_ppgtt *ppgtt = dev_priv->mm.aliasing_ppgtt; + int i, j, ret; + + /* bit of a hack to find the actual last used pd */ + int used_pd = ppgtt->num_pd_entries / GEN8_PDES_PER_PAGE; + + for_each_ring(ring, dev_priv, j) { + I915_WRITE(RING_MODE_GEN7(ring), + _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); + } + + for (i = used_pd - 1; i >= 0; i--) { + dma_addr_t addr = ppgtt->pd_dma_addr[i]; + for_each_ring(ring, dev_priv, j) { + ret = gen8_write_pdp(ring, i, addr); + if (ret) + return ret; + } + } + return 0; +} + static void gen8_ppgtt_clear_range(struct i915_address_space *vm, unsigned first_entry, unsigned num_entries, @@ -326,6 +375,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt, uint64_t size) ppgtt->num_pd_pages = 1 << get_order(max_pdp << PAGE_SHIFT); ppgtt->num_pt_pages = 1 << get_order(num_pt_pages << PAGE_SHIFT); ppgtt->num_pd_entries = max_pdp * GEN8_PDES_PER_PAGE; + ppgtt->enable = gen8_ppgtt_enable; ppgtt->base.clear_range = gen8_ppgtt_clear_range; ppgtt->base.insert_entries = gen8_ppgtt_insert_entries; ppgtt->base.cleanup = gen8_ppgtt_cleanup;