[Intel-gfx] [PATCH v6 08/19] drm/i915/gen8: Add 4 level switching infrastructure and lrc support
Goel, Akash
akash.goel at intel.com
Wed Jul 29 21:14:15 PDT 2015
On 7/29/2015 9:53 PM, Michel Thierry wrote:
> In 64b (48bit canonical) PPGTT addressing, the PDP0 register contains
> the base address to PML4, while the other PDP registers are ignored.
>
> In LRC, the addressing mode must be specified in every context
> descriptor, and the base address to PML4 is stored in the reg state.
>
> v2: PML4 update in legacy context switch is left for historic reasons,
> the preferred mode of operation is with lrc context based submission.
> v3: s/gen8_map_page_directory/gen8_setup_page_directory and
> s/gen8_map_page_directory_pointer/gen8_setup_page_directory_pointer.
> Also, clflush will be needed for bxt. (Akash)
> v4: Squashed lrc-specific code and use a macro to set PML4 register.
> v5: Rebase after Mika's ppgtt cleanup / scratch merge patch series.
> PDP update in bb_start is only for legacy 32b mode.
> v6: Rebase after final merged version of Mika's ppgtt/scratch
> patches.
> v7: There is no need to update the pml4 register value in
> execlists_update_context. (Akash)
> v8: Move pd and pdp setup functions to a previous patch, they do not
> belong here. (Akash)
>
> Cc: Akash Goel <akash.goel at intel.com>
> Signed-off-by: Ben Widawsky <ben at bwidawsk.net>
> Signed-off-by: Michel Thierry <michel.thierry at intel.com> (v2+)
> ---
> drivers/gpu/drm/i915/i915_gem_gtt.c | 17 +++++++----
> drivers/gpu/drm/i915/i915_reg.h | 1 +
> drivers/gpu/drm/i915/intel_lrc.c | 60 ++++++++++++++++++++++++++-----------
> 3 files changed, 55 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c
> index 4179b80..c6c8af7 100644
> --- a/drivers/gpu/drm/i915/i915_gem_gtt.c
> +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c
> @@ -656,8 +656,8 @@ static int gen8_write_pdp(struct drm_i915_gem_request *req,
> return 0;
> }
>
> -static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
> - struct drm_i915_gem_request *req)
> +static int gen8_legacy_mm_switch(struct i915_hw_ppgtt *ppgtt,
> + struct drm_i915_gem_request *req)
> {
> int i, ret;
>
> @@ -672,6 +672,12 @@ static int gen8_mm_switch(struct i915_hw_ppgtt *ppgtt,
> return 0;
> }
>
> +static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
> + struct drm_i915_gem_request *req)
> +{
> + return gen8_write_pdp(req, 0, px_dma(&ppgtt->pml4));
> +}
> +
> static void gen8_ppgtt_clear_pte_range(struct i915_address_space *vm,
> struct i915_page_directory_pointer *pdp,
> uint64_t start,
> @@ -1318,14 +1324,13 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
> ppgtt->base.unbind_vma = ppgtt_unbind_vma;
> ppgtt->base.bind_vma = ppgtt_bind_vma;
>
> - ppgtt->switch_mm = gen8_mm_switch;
> -
> if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
> ret = setup_px(ppgtt->base.dev, &ppgtt->pml4);
> if (ret)
> goto free_scratch;
>
> ppgtt->base.total = 1ULL << 48;
> + ppgtt->switch_mm = gen8_48b_mm_switch;
> } else {
> ret = __pdp_init(false, &ppgtt->pdp);
> if (ret)
> @@ -1340,6 +1345,7 @@ static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
> */
> ppgtt->base.total = to_i915(ppgtt->base.dev)->gtt.base.total;
>
> + ppgtt->switch_mm = gen8_legacy_mm_switch;
> trace_i915_page_directory_pointer_entry_alloc(&ppgtt->base,
> 0, 0,
> GEN8_PML4E_SHIFT);
> @@ -1537,8 +1543,9 @@ static void gen8_ppgtt_enable(struct drm_device *dev)
> int j;
>
> for_each_ring(ring, dev_priv, j) {
> + u32 four_level = USES_FULL_48BIT_PPGTT(dev) ? GEN8_GFX_PPGTT_48B : 0;
> I915_WRITE(RING_MODE_GEN7(ring),
> - _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
> + _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level));
> }
> }
>
> diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
> index 3a77678..5bd1b6a 100644
> --- a/drivers/gpu/drm/i915/i915_reg.h
> +++ b/drivers/gpu/drm/i915/i915_reg.h
> @@ -1670,6 +1670,7 @@ enum skl_disp_power_wells {
> #define GFX_REPLAY_MODE (1<<11)
> #define GFX_PSMI_GRANULARITY (1<<10)
> #define GFX_PPGTT_ENABLE (1<<9)
> +#define GEN8_GFX_PPGTT_48B (1<<7)
>
> #define VLV_DISPLAY_BASE 0x180000
> #define VLV_MIPI_BASE VLV_DISPLAY_BASE
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index 99bba8e..0b65188 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -196,13 +196,21 @@
> reg_state[CTX_PDP ## n ## _LDW+1] = lower_32_bits(_addr); \
> }
>
> +#define ASSIGN_CTX_PML4(ppgtt, reg_state) { \
> + reg_state[CTX_PDP0_UDW + 1] = upper_32_bits(px_dma(&ppgtt->pml4)); \
> + reg_state[CTX_PDP0_LDW + 1] = lower_32_bits(px_dma(&ppgtt->pml4)); \
> +}
> +
> enum {
> ADVANCED_CONTEXT = 0,
> - LEGACY_CONTEXT,
> + LEGACY_32B_CONTEXT,
> ADVANCED_AD_CONTEXT,
> LEGACY_64B_CONTEXT
> };
> -#define GEN8_CTX_MODE_SHIFT 3
> +#define GEN8_CTX_ADDRESSING_MODE_SHIFT 3
> +#define GEN8_CTX_ADDRESSING_MODE(dev) (USES_FULL_48BIT_PPGTT(dev) ?\
> + LEGACY_64B_CONTEXT :\
> + LEGACY_32B_CONTEXT)
> enum {
> FAULT_AND_HANG = 0,
> FAULT_AND_HALT, /* Debug only */
> @@ -273,7 +281,7 @@ static uint64_t execlists_ctx_descriptor(struct drm_i915_gem_request *rq)
> WARN_ON(lrca & 0xFFFFFFFF00000FFFULL);
>
> desc = GEN8_CTX_VALID;
> - desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT;
> + desc |= GEN8_CTX_ADDRESSING_MODE(dev) << GEN8_CTX_ADDRESSING_MODE_SHIFT;
> if (IS_GEN8(ctx_obj->base.dev))
> desc |= GEN8_CTX_L3LLC_COHERENT;
> desc |= GEN8_CTX_PRIVILEGE;
> @@ -348,10 +356,12 @@ static int execlists_update_context(struct drm_i915_gem_request *rq)
> reg_state[CTX_RING_TAIL+1] = rq->tail;
> reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(rb_obj);
>
> - /* True PPGTT with dynamic page allocation: update PDP registers and
> - * point the unallocated PDPs to the scratch page
> - */
> - if (ppgtt) {
> + if (ppgtt && !USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
> + /* True 32b PPGTT with dynamic page allocation: update PDP
> + * registers and point the unallocated PDPs to scratch page.
> + * PML4 is allocated during ppgtt init, so this is not needed
> + * in 48-bit mode.
> + */
> ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
> ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
> ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
> @@ -1512,12 +1522,15 @@ static int gen8_emit_bb_start(struct drm_i915_gem_request *req,
> * Ideally, we should set Force PD Restore in ctx descriptor,
> * but we can't. Force Restore would be a second option, but
> * it is unsafe in case of lite-restore (because the ctx is
> - * not idle). */
> + * not idle). PML4 is allocated during ppgtt init so this is
> + * not needed in 48-bit.*/
> if (req->ctx->ppgtt &&
> (intel_ring_flag(req->ring) & req->ctx->ppgtt->pd_dirty_rings)) {
> - ret = intel_logical_ring_emit_pdps(req);
> - if (ret)
> - return ret;
> + if (GEN8_CTX_ADDRESSING_MODE(req->i915) == LEGACY_32B_CONTEXT) {
Sorry for the late comment.
For consistency, better to use 'USES_FULL_48BIT_PPGTT' macro only here,
as that will also imply the same thing i.e. which type of Context
addressing mode is being used.
Best regards
Akash
> + ret = intel_logical_ring_emit_pdps(req);
> + if (ret)
> + return ret;
> + }
>
> req->ctx->ppgtt->pd_dirty_rings &= ~intel_ring_flag(req->ring);
> }
> @@ -2198,13 +2211,24 @@ populate_lr_context(struct intel_context *ctx, struct drm_i915_gem_object *ctx_o
> reg_state[CTX_PDP0_UDW] = GEN8_RING_PDP_UDW(ring, 0);
> reg_state[CTX_PDP0_LDW] = GEN8_RING_PDP_LDW(ring, 0);
>
> - /* With dynamic page allocation, PDPs may not be allocated at this point,
> - * Point the unallocated PDPs to the scratch page
> - */
> - ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
> - ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
> - ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
> - ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
> + if (USES_FULL_48BIT_PPGTT(ppgtt->base.dev)) {
> + /* 64b PPGTT (48bit canonical)
> + * PDP0_DESCRIPTOR contains the base address to PML4 and
> + * other PDP Descriptors are ignored.
> + */
> + ASSIGN_CTX_PML4(ppgtt, reg_state);
> + } else {
> + /* 32b PPGTT
> + * PDP*_DESCRIPTOR contains the base address of space supported.
> + * With dynamic page allocation, PDPs may not be allocated at
> + * this point. Point the unallocated PDPs to the scratch page
> + */
> + ASSIGN_CTX_PDP(ppgtt, reg_state, 3);
> + ASSIGN_CTX_PDP(ppgtt, reg_state, 2);
> + ASSIGN_CTX_PDP(ppgtt, reg_state, 1);
> + ASSIGN_CTX_PDP(ppgtt, reg_state, 0);
> + }
> +
> if (ring->id == RCS) {
> reg_state[CTX_LRI_HEADER_2] = MI_LOAD_REGISTER_IMM(1);
> reg_state[CTX_R_PWR_CLK_STATE] = GEN8_R_PWR_CLK_STATE;
>
More information about the Intel-gfx
mailing list