Commit 33e7a975 authored by Ville Syrjälä's avatar Ville Syrjälä Committed by Imre Deak

drm/i915/xelpd: First stab at DPT support

Add support for DPT (display page table). DPT is a
slightly peculiar two level page table scheme used for
tiled scanout buffers (linear uses direct ggtt mapping
still). The plane surface address will point at a page
in the DPT which holds the PTEs for 512 actual pages.
Thus we require 1/512 of the ggttt address space
compared to a direct ggtt mapping.

We create a new DPT address space for each framebuffer and
track two vmas (one for the DPT, another for the ggtt).

TODO:
- Is the i915_address_space approaach sane?
- Maybe don't map the whole DPT to write the PTEs?
- Deal with remapping/rotation? Need to create a
  separate DPT for each remapped/rotated plane I
  guess. Or else we'd need to make the per-fb DPT
  large enough to support potentially several
  remapped/rotated vmas. How large should that be?
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Signed-off-by: default avatarBommu Krishnaiah <krishnaiah.bommu@intel.com>
Cc: Wilson Chris P <Chris.P.Wilson@intel.com>
Cc: Tang CQ <cq.tang@intel.com>
Cc: Auld Matthew <matthew.auld@intel.com>
Reviewed-by: default avatarUma Shankar <uma.shankar@intel.com>
Reviewed-by: default avatarWilson Chris P <Chris.P.Wilson@intel.com>
Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210506161930.309688-5-imre.deak@intel.com
parent bdd27cad
...@@ -102,7 +102,8 @@ intel_plane_duplicate_state(struct drm_plane *plane) ...@@ -102,7 +102,8 @@ intel_plane_duplicate_state(struct drm_plane *plane)
__drm_atomic_helper_plane_duplicate_state(plane, &intel_state->uapi); __drm_atomic_helper_plane_duplicate_state(plane, &intel_state->uapi);
intel_state->vma = NULL; intel_state->ggtt_vma = NULL;
intel_state->dpt_vma = NULL;
intel_state->flags = 0; intel_state->flags = 0;
/* add reference to fb */ /* add reference to fb */
...@@ -125,7 +126,9 @@ intel_plane_destroy_state(struct drm_plane *plane, ...@@ -125,7 +126,9 @@ intel_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *state) struct drm_plane_state *state)
{ {
struct intel_plane_state *plane_state = to_intel_plane_state(state); struct intel_plane_state *plane_state = to_intel_plane_state(state);
drm_WARN_ON(plane->dev, plane_state->vma);
drm_WARN_ON(plane->dev, plane_state->ggtt_vma);
drm_WARN_ON(plane->dev, plane_state->dpt_vma);
__drm_atomic_helper_plane_destroy_state(&plane_state->uapi); __drm_atomic_helper_plane_destroy_state(&plane_state->uapi);
if (plane_state->hw.fb) if (plane_state->hw.fb)
......
...@@ -43,6 +43,7 @@ struct drm_mode_fb_cmd2; ...@@ -43,6 +43,7 @@ struct drm_mode_fb_cmd2;
struct drm_modeset_acquire_ctx; struct drm_modeset_acquire_ctx;
struct drm_plane; struct drm_plane;
struct drm_plane_state; struct drm_plane_state;
struct i915_address_space;
struct i915_ggtt_view; struct i915_ggtt_view;
struct intel_atomic_state; struct intel_atomic_state;
struct intel_crtc; struct intel_crtc;
......
...@@ -128,6 +128,8 @@ struct intel_framebuffer { ...@@ -128,6 +128,8 @@ struct intel_framebuffer {
struct intel_fb_view normal_view; struct intel_fb_view normal_view;
struct intel_fb_view rotated_view; struct intel_fb_view rotated_view;
struct intel_fb_view remapped_view; struct intel_fb_view remapped_view;
struct i915_address_space *dpt_vm;
}; };
struct intel_fbdev { struct intel_fbdev {
...@@ -610,7 +612,8 @@ struct intel_plane_state { ...@@ -610,7 +612,8 @@ struct intel_plane_state {
enum drm_scaling_filter scaling_filter; enum drm_scaling_filter scaling_filter;
} hw; } hw;
struct i915_vma *vma; struct i915_vma *ggtt_vma;
struct i915_vma *dpt_vma;
unsigned long flags; unsigned long flags;
#define PLANE_HAS_FENCE BIT(0) #define PLANE_HAS_FENCE BIT(0)
...@@ -1972,9 +1975,15 @@ intel_wait_for_vblank_if_active(struct drm_i915_private *dev_priv, enum pipe pip ...@@ -1972,9 +1975,15 @@ intel_wait_for_vblank_if_active(struct drm_i915_private *dev_priv, enum pipe pip
intel_wait_for_vblank(dev_priv, pipe); intel_wait_for_vblank(dev_priv, pipe);
} }
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *state) static inline bool intel_fb_uses_dpt(const struct drm_framebuffer *fb)
{
return fb && DISPLAY_VER(to_i915(fb->dev)) >= 13 &&
fb->modifier != DRM_FORMAT_MOD_LINEAR;
}
static inline u32 intel_plane_ggtt_offset(const struct intel_plane_state *plane_state)
{ {
return i915_ggtt_offset(state->vma); return i915_ggtt_offset(plane_state->ggtt_vma);
} }
static inline struct intel_frontbuffer * static inline struct intel_frontbuffer *
......
...@@ -737,11 +737,11 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc, ...@@ -737,11 +737,11 @@ static void intel_fbc_update_state_cache(struct intel_crtc *crtc,
cache->fence_y_offset = intel_plane_fence_y_offset(plane_state); cache->fence_y_offset = intel_plane_fence_y_offset(plane_state);
drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE && drm_WARN_ON(&dev_priv->drm, plane_state->flags & PLANE_HAS_FENCE &&
!plane_state->vma->fence); !plane_state->ggtt_vma->fence);
if (plane_state->flags & PLANE_HAS_FENCE && if (plane_state->flags & PLANE_HAS_FENCE &&
plane_state->vma->fence) plane_state->ggtt_vma->fence)
cache->fence_id = plane_state->vma->fence->id; cache->fence_id = plane_state->ggtt_vma->fence->id;
else else
cache->fence_id = -1; cache->fence_id = -1;
......
...@@ -934,6 +934,21 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state, ...@@ -934,6 +934,21 @@ static u32 glk_plane_color_ctl(const struct intel_crtc_state *crtc_state,
return plane_color_ctl; return plane_color_ctl;
} }
static u32 skl_surf_address(const struct intel_plane_state *plane_state,
int color_plane)
{
const struct drm_framebuffer *fb = plane_state->hw.fb;
u32 offset = plane_state->view.color_plane[color_plane].offset;
if (intel_fb_uses_dpt(fb)) {
WARN_ON(offset & 0x1fffff);
return offset >> 9;
} else {
WARN_ON(offset & 0xfff);
return offset;
}
}
static void static void
skl_program_plane(struct intel_plane *plane, skl_program_plane(struct intel_plane *plane,
const struct intel_crtc_state *crtc_state, const struct intel_crtc_state *crtc_state,
...@@ -944,7 +959,7 @@ skl_program_plane(struct intel_plane *plane, ...@@ -944,7 +959,7 @@ skl_program_plane(struct intel_plane *plane,
enum plane_id plane_id = plane->id; enum plane_id plane_id = plane->id;
enum pipe pipe = plane->pipe; enum pipe pipe = plane->pipe;
const struct drm_intel_sprite_colorkey *key = &plane_state->ckey; const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
u32 surf_addr = plane_state->view.color_plane[color_plane].offset; u32 surf_addr = skl_surf_address(plane_state, color_plane);
u32 stride = skl_plane_stride(plane_state, color_plane); u32 stride = skl_plane_stride(plane_state, color_plane);
const struct drm_framebuffer *fb = plane_state->hw.fb; const struct drm_framebuffer *fb = plane_state->hw.fb;
int aux_plane = skl_main_to_aux_plane(fb, color_plane); int aux_plane = skl_main_to_aux_plane(fb, color_plane);
...@@ -983,7 +998,7 @@ skl_program_plane(struct intel_plane *plane, ...@@ -983,7 +998,7 @@ skl_program_plane(struct intel_plane *plane,
} }
if (aux_plane) { if (aux_plane) {
aux_dist = plane_state->view.color_plane[aux_plane].offset - surf_addr; aux_dist = skl_surf_address(plane_state, aux_plane) - surf_addr;
if (DISPLAY_VER(dev_priv) < 12) if (DISPLAY_VER(dev_priv) < 12)
aux_dist |= skl_plane_stride(plane_state, aux_plane); aux_dist |= skl_plane_stride(plane_state, aux_plane);
......
...@@ -6,8 +6,15 @@ ...@@ -6,8 +6,15 @@
#ifndef __GEN8_PPGTT_H__ #ifndef __GEN8_PPGTT_H__
#define __GEN8_PPGTT_H__ #define __GEN8_PPGTT_H__
#include <linux/kernel.h>
struct i915_address_space;
struct intel_gt; struct intel_gt;
enum i915_cache_level;
struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt); struct i915_ppgtt *gen8_ppgtt_create(struct intel_gt *gt);
u64 gen8_ggtt_pte_encode(dma_addr_t addr,
enum i915_cache_level level,
u32 flags);
#endif #endif
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "i915_vgpu.h" #include "i915_vgpu.h"
#include "intel_gtt.h" #include "intel_gtt.h"
#include "gen8_ppgtt.h"
static int static int
i915_get_ggtt_vma_pages(struct i915_vma *vma); i915_get_ggtt_vma_pages(struct i915_vma *vma);
...@@ -187,9 +188,9 @@ static void gmch_ggtt_invalidate(struct i915_ggtt *ggtt) ...@@ -187,9 +188,9 @@ static void gmch_ggtt_invalidate(struct i915_ggtt *ggtt)
intel_gtt_chipset_flush(); intel_gtt_chipset_flush();
} }
static u64 gen8_ggtt_pte_encode(dma_addr_t addr, u64 gen8_ggtt_pte_encode(dma_addr_t addr,
enum i915_cache_level level, enum i915_cache_level level,
u32 flags) u32 flags)
{ {
gen8_pte_t pte = addr | _PAGE_PRESENT; gen8_pte_t pte = addr | _PAGE_PRESENT;
......
...@@ -245,6 +245,7 @@ struct i915_address_space { ...@@ -245,6 +245,7 @@ struct i915_address_space {
struct dma_resv resv; /* reservation lock for all pd objects, and buffer pool */ struct dma_resv resv; /* reservation lock for all pd objects, and buffer pool */
#define VM_CLASS_GGTT 0 #define VM_CLASS_GGTT 0
#define VM_CLASS_PPGTT 1 #define VM_CLASS_PPGTT 1
#define VM_CLASS_DPT 2
struct drm_i915_gem_object *scratch[4]; struct drm_i915_gem_object *scratch[4];
/** /**
...@@ -255,6 +256,9 @@ struct i915_address_space { ...@@ -255,6 +256,9 @@ struct i915_address_space {
/* Global GTT */ /* Global GTT */
bool is_ggtt:1; bool is_ggtt:1;
/* Display page table */
bool is_dpt:1;
/* Some systems support read-only mappings for GGTT and/or PPGTT */ /* Some systems support read-only mappings for GGTT and/or PPGTT */
bool has_read_only:1; bool has_read_only:1;
...@@ -351,6 +355,7 @@ struct i915_ppgtt { ...@@ -351,6 +355,7 @@ struct i915_ppgtt {
}; };
#define i915_is_ggtt(vm) ((vm)->is_ggtt) #define i915_is_ggtt(vm) ((vm)->is_ggtt)
#define i915_is_dpt(vm) ((vm)->is_dpt)
int __must_check int __must_check
i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww); i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment