Commit 54d4d719 authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Overcome display engine stride limits via GTT remapping

The display engine stride limits are getting in our way. On SKL+
we are limited to 8k pixels, which is easily exceeded with three
4k displays. To overcome this limitation we can remap the pages
in the GTT to provide the display engine with a view of memory
with a smaller stride.

The code is mostly already there as We already play tricks with
the plane surface address and x/y offsets.

A few caveats apply:
* linear buffers need the fb stride to be page aligned, as
  otherwise the remapped lines wouldn't start at the same
  spot
* compressed buffers can't be remapped due to the new
  ccs hash mode causing the virtual address of the pages
  to affect the interpretation of the compressed data. IIRC
  the old hash was limited to the low 12 bits so if we were
  using that mode we could remap. As it stands we just refuse
  to remapp with compressed fbs.
* no remapping gen2/3 as we'd need a fence for the remapped
  vma, which we currently don't have. Need to deal with the
  fence POT requirements, and do something about the gen2
  gtt page size vs tile size difference

v2: Rebase due to is_ccs_modifier()
    Fix up the skl+ stride_mult mess
    memset() the gtt_view because otherwise we could leave
    junk in plane[1] when going from 2 plane to 1 plane format
v3: intel_check_plane_stride() was split out
v4: Drop the aligned viewport stuff, it was meant for ccs which
    can't be remapped anyway
v5: Introduce intel_plane_can_remap()
    Reorder the code so that plane_state->view gets filled
    even for invisible planes, otherwise we'd keep using
    stale values and could explode during remapping. The new
    logic never remaps invisible planes since we don't have
    a viewport, and instead pins the full fb instead
v6: Fix plane src coord checks after remapping by moving
    plane_state->base.src to the final plane x/y offsets.
    Allow intel_plane_check_stride() to fail even with
    remapping (can happen at least with a linear 64bpp
    fb with a 4k plane and a suitably inconvenient src
    coordinates).
    Improve aux plane FIXME (Daniel)
    Move some code shuffling into a separate patch (Daniel)

Testcase: igt/kms_big_fb
Cc: Daniel Vetter <daniel@ffwll.ch>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190509122159.24376-6-ville.syrjala@linux.intel.comReviewed-by: default avatarMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
parent a88c40eb
This diff is collapsed.
......@@ -29,6 +29,7 @@
#include <drm/i915_drm.h>
struct drm_i915_private;
struct intel_plane_state;
enum i915_gpio {
GPIOA,
......@@ -435,5 +436,6 @@ void intel_link_compute_m_n(u16 bpp, int nlanes,
bool constant_n);
bool is_ccs_modifier(u64 modifier);
void lpt_disable_clkout_dp(struct drm_i915_private *dev_priv);
bool intel_plane_can_remap(const struct intel_plane_state *plane_state);
#endif
......@@ -256,6 +256,16 @@ int intel_plane_check_stride(const struct intel_plane_state *plane_state)
unsigned int rotation = plane_state->base.rotation;
u32 stride, max_stride;
/*
* We ignore stride for all invisible planes that
* can be remapped. Otherwise we could end up
* with a false positive when the remapping didn't
* kick in due the plane being invisible.
*/
if (intel_plane_can_remap(plane_state) &&
!plane_state->base.visible)
return 0;
/* FIXME other color planes? */
stride = plane_state->color_plane[0].stride;
max_stride = plane->max_stride(plane, fb->format->format,
......@@ -1417,6 +1427,10 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = i9xx_check_plane_surface(plane_state);
if (ret)
return ret;
if (!plane_state->base.visible)
return 0;
......@@ -1428,10 +1442,6 @@ g4x_sprite_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = i9xx_check_plane_surface(plane_state);
if (ret)
return ret;
if (INTEL_GEN(dev_priv) >= 7)
plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
else
......@@ -1475,6 +1485,10 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = i9xx_check_plane_surface(plane_state);
if (ret)
return ret;
if (!plane_state->base.visible)
return 0;
......@@ -1482,10 +1496,6 @@ vlv_sprite_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = i9xx_check_plane_surface(plane_state);
if (ret)
return ret;
plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
return 0;
......@@ -1639,6 +1649,10 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = skl_check_plane_surface(plane_state);
if (ret)
return ret;
if (!plane_state->base.visible)
return 0;
......@@ -1654,10 +1668,6 @@ static int skl_plane_check(struct intel_crtc_state *crtc_state,
if (ret)
return ret;
ret = skl_check_plane_surface(plane_state);
if (ret)
return ret;
/* HW only has 8 bits pixel precision, disable plane if invisible */
if (!(plane_state->base.alpha >> 8))
plane_state->base.visible = false;
......
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