Re: [PATCH 27/62] drm/i915/bdw: Implement PPGTT enable

Damien Lespiau
2013-11-04T14:48:02Z

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