Re: [PATCH 07/12] drm/i915/bdw: Support 64 bit PPGTT in lrc mode

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Feb 20, 2015 at 11:16 PM, Michel Thierry
<michel.thierry@xxxxxxxxx> wrote:
> In 64b (48bit canonical) PPGTT addressing, the PDP0 register contains
> the base address to PML4, while the other PDP registers are ignored.
>
> Also, the addressing mode must be specified in every context descriptor.
>
> Signed-off-by: Michel Thierry <michel.thierry@xxxxxxxxx>
> ---
>  drivers/gpu/drm/i915/intel_lrc.c | 167 ++++++++++++++++++++++++++-------------
>  1 file changed, 114 insertions(+), 53 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
> index f461631..2b6d262 100644
> --- a/drivers/gpu/drm/i915/intel_lrc.c
> +++ b/drivers/gpu/drm/i915/intel_lrc.c
> @@ -255,7 +255,8 @@ u32 intel_execlists_ctx_id(struct drm_i915_gem_object *ctx_obj)
>  }
>
>  static uint64_t execlists_ctx_descriptor(struct intel_engine_cs *ring,
> -                                        struct drm_i915_gem_object *ctx_obj)
> +                                        struct drm_i915_gem_object *ctx_obj,
> +                                        bool legacy_64bit_ctx)

The 'legacy_64bit_ctx' flag can be derived within the
execlists_ctx_descriptor function also,
through USES_FULL_48BIT_PPGTT macro, as 'dev' pointer is already available.
Doing so, will avoid the modification of  function’s prototype and
modification to ‘execlists_elsp_write’.

>  {
>         struct drm_device *dev = ring->dev;
>         uint64_t desc;
> @@ -264,7 +265,10 @@ static uint64_t execlists_ctx_descriptor(struct intel_engine_cs *ring,
>         WARN_ON(lrca & 0xFFFFFFFF00000FFFULL);
>
>         desc = GEN8_CTX_VALID;
> -       desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT;
> +       if (legacy_64bit_ctx)
> +               desc |= LEGACY_64B_CONTEXT << GEN8_CTX_MODE_SHIFT;
> +       else
> +               desc |= LEGACY_CONTEXT << GEN8_CTX_MODE_SHIFT;
>         desc |= GEN8_CTX_L3LLC_COHERENT;
>         desc |= GEN8_CTX_PRIVILEGE;
>         desc |= lrca;
> @@ -292,16 +296,17 @@ static void execlists_elsp_write(struct intel_engine_cs *ring,
>         struct drm_i915_private *dev_priv = dev->dev_private;
>         uint64_t temp = 0;
>         uint32_t desc[4];
> +       bool legacy_64bit_ctx = USES_FULL_48BIT_PPGTT(dev);
>
>         /* XXX: You must always write both descriptors in the order below. */
>         if (ctx_obj1)
> -               temp = execlists_ctx_descriptor(ring, ctx_obj1);
> +               temp = execlists_ctx_descriptor(ring, ctx_obj1, legacy_64bit_ctx);
>         else
>                 temp = 0;
>         desc[1] = (u32)(temp >> 32);
>         desc[0] = (u32)temp;
>
> -       temp = execlists_ctx_descriptor(ring, ctx_obj0);
> +       temp = execlists_ctx_descriptor(ring, ctx_obj0, legacy_64bit_ctx);
>         desc[3] = (u32)(temp >> 32);
>         desc[2] = (u32)temp;
>
> @@ -332,37 +337,60 @@ static int execlists_update_context(struct drm_i915_gem_object *ctx_obj,
>         reg_state[CTX_RING_TAIL+1] = tail;
>         reg_state[CTX_RING_BUFFER_START+1] = i915_gem_obj_ggtt_offset(ring_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 64b PPGTT (48bit canonical)
> +                * PDP0_DESCRIPTOR contains the base address to PML4 and
> +                * other PDP Descriptors are ignored
> +                */
> +               reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pml4.daddr);
> +               reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pml4.daddr);
> +       } else if (ppgtt) {
> +               /* True 32b PPGTT with dynamic page allocation: update PDP
> +                * registers and point the unallocated PDPs to the scratch page
> +                */
>                 if (test_bit(3, ppgtt->pdp.used_pdpes)) {
> -                       reg_state[CTX_PDP3_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> -                       reg_state[CTX_PDP3_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> +                       reg_state[CTX_PDP3_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> +                       reg_state[CTX_PDP3_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
>                 } else {
> -                       reg_state[CTX_PDP3_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -                       reg_state[CTX_PDP3_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP3_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP3_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
>                 }
>                 if (test_bit(2, ppgtt->pdp.used_pdpes)) {
> -                       reg_state[CTX_PDP2_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> -                       reg_state[CTX_PDP2_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> +                       reg_state[CTX_PDP2_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> +                       reg_state[CTX_PDP2_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
>                 } else {
> -                       reg_state[CTX_PDP2_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -                       reg_state[CTX_PDP2_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP2_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP2_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
>                 }
>                 if (test_bit(1, ppgtt->pdp.used_pdpes)) {
> -                       reg_state[CTX_PDP1_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> -                       reg_state[CTX_PDP1_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> +                       reg_state[CTX_PDP1_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> +                       reg_state[CTX_PDP1_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[1]->daddr);
>                 } else {
> -                       reg_state[CTX_PDP1_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -                       reg_state[CTX_PDP1_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP1_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP1_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
>                 }
>                 if (test_bit(0, ppgtt->pdp.used_pdpes)) {
> -                       reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> -                       reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> +                       reg_state[CTX_PDP0_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> +                       reg_state[CTX_PDP0_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[0]->daddr);
>                 } else {
> -                       reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -                       reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP0_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP0_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
>                 }
>         }
>
> @@ -1771,36 +1799,69 @@ 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
> -        */
> -       if (test_bit(3, ppgtt->pdp.used_pdpes)) {
> -               reg_state[CTX_PDP3_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> -               reg_state[CTX_PDP3_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> -       } else {
> -               reg_state[CTX_PDP3_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -               reg_state[CTX_PDP3_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> -       }
> -       if (test_bit(2, ppgtt->pdp.used_pdpes)) {
> -               reg_state[CTX_PDP2_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> -               reg_state[CTX_PDP2_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> -       } else {
> -               reg_state[CTX_PDP2_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -               reg_state[CTX_PDP2_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> -       }
> -       if (test_bit(1, ppgtt->pdp.used_pdpes)) {
> -               reg_state[CTX_PDP1_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> -               reg_state[CTX_PDP1_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> -       } else {
> -               reg_state[CTX_PDP1_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -               reg_state[CTX_PDP1_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> -       }
> -       if (test_bit(0, ppgtt->pdp.used_pdpes)) {
> -               reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> -               reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> +       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
> +                */
> +               reg_state[CTX_PDP3_UDW+1] = 0;
> +               reg_state[CTX_PDP3_LDW+1] = 0;
> +               reg_state[CTX_PDP2_UDW+1] = 0;
> +               reg_state[CTX_PDP2_LDW+1] = 0;
> +               reg_state[CTX_PDP1_UDW+1] = 0;
> +               reg_state[CTX_PDP1_LDW+1] = 0;
> +               reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->pml4.daddr);
> +               reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->pml4.daddr);
>         } else {
> -               reg_state[CTX_PDP0_UDW+1] = upper_32_bits(ppgtt->scratch_pd->daddr);
> -               reg_state[CTX_PDP0_LDW+1] = lower_32_bits(ppgtt->scratch_pd->daddr);
> +               /* 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
> +                */
> +               if (test_bit(3, ppgtt->pdp.used_pdpes)) {
> +                       reg_state[CTX_PDP3_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> +                       reg_state[CTX_PDP3_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[3]->daddr);
> +               } else {
> +                       reg_state[CTX_PDP3_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP3_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
> +               }
> +               if (test_bit(2, ppgtt->pdp.used_pdpes)) {
> +                       reg_state[CTX_PDP2_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> +                       reg_state[CTX_PDP2_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[2]->daddr);
> +               } else {
> +                       reg_state[CTX_PDP2_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP2_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
> +               }
> +               if (test_bit(1, ppgtt->pdp.used_pdpes)) {
> +                       reg_state[CTX_PDP1_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> +                       reg_state[CTX_PDP1_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[1]->daddr);
> +               } else {
> +                       reg_state[CTX_PDP1_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP1_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
> +               }
> +               if (test_bit(0, ppgtt->pdp.used_pdpes)) {
> +                       reg_state[CTX_PDP0_UDW+1] =
> +                                       upper_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> +                       reg_state[CTX_PDP0_LDW+1] =
> +                                       lower_32_bits(ppgtt->pdp.page_directory[0]->daddr);
> +               } else {
> +                       reg_state[CTX_PDP0_UDW+1] =
> +                                       upper_32_bits(ppgtt->scratch_pd->daddr);
> +                       reg_state[CTX_PDP0_LDW+1] =
> +                                       lower_32_bits(ppgtt->scratch_pd->daddr);
> +               }
>         }
>
>         if (ring->id == RCS) {
> --
> 2.1.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
> http://lists.freedesktop.org/mailman/listinfo/intel-gfx
_______________________________________________
Intel-gfx mailing list
Intel-gfx@xxxxxxxxxxxxxxxxxxxxx
http://lists.freedesktop.org/mailman/listinfo/intel-gfx





[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux